Compare commits
4
Commits
cb262aa51f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9b913c0fa | ||
|
|
7500c0aa83 | ||
|
|
7675a3742d
|
||
|
|
5831a8e2d2
|
+7
-1
@@ -1,5 +1,5 @@
|
||||
const QuitText = struct {
|
||||
const text = "Press ctrl+c to quit. Press ctrl+n to launch `vim`.";
|
||||
const text = "Press ctrl+c to quit. Press ctrl+n to launch `vim`. Press space to yank to system clipboard.";
|
||||
|
||||
pub fn element(this: *@This()) App.Element {
|
||||
return .{ .ptr = this, .vtable = &.{ .content = content } };
|
||||
@@ -150,6 +150,12 @@ pub fn main(init: std.process.Init) !void {
|
||||
.key => |key| {
|
||||
if (key.eql(.{ .cp = 'c', .mod = .{ .ctrl = true } })) try app.quit();
|
||||
|
||||
if (key.eql(.{ .cp = zterm.input.Space })) try app.yankToSystemClipboard(
|
||||
w,
|
||||
gpa,
|
||||
"This is a test of the OSC52 support:\n\tWith multiple lines and some special characters $?/-[]().╭─╮",
|
||||
);
|
||||
|
||||
if (key.eql(.{ .cp = 'n', .mod = .{ .ctrl = true } })) {
|
||||
try app.stop(w);
|
||||
try w.flush();
|
||||
|
||||
+7
-3
@@ -76,8 +76,9 @@ pub fn main(init: std.process.Init) !void {
|
||||
|
||||
var app: App = .init(gpa, io, .{});
|
||||
var stdout = std.Io.File.stdout();
|
||||
var buffer: [4096]u8 = undefined;
|
||||
var writer = stdout.writerStreaming(io, &buffer);
|
||||
// var buffer: [4096]u8 = undefined;
|
||||
// var writer = stdout.writerStreaming(io, &buffer);
|
||||
var writer = stdout.writerStreaming(io, &.{});
|
||||
const w = &writer.interface;
|
||||
|
||||
var renderer = zterm.Renderer.Direct.init(gpa);
|
||||
@@ -158,7 +159,10 @@ pub fn main(init: std.process.Init) !void {
|
||||
defer gpa.free(line);
|
||||
log.debug("{s}", .{line});
|
||||
|
||||
if (std.mem.eql(u8, line, "q\n")) try app.quit();
|
||||
if (std.mem.eql(u8, line, "q\n")) {
|
||||
try app.quit();
|
||||
break :event;
|
||||
}
|
||||
},
|
||||
// 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 }),
|
||||
|
||||
+20
-4
@@ -28,8 +28,6 @@ pub fn App(comptime M: type, comptime E: type) type {
|
||||
io: std.Io,
|
||||
model: Model,
|
||||
queue: Queue,
|
||||
// thread: ?Thread = null,
|
||||
// quit_event: Thread.ResetEvent,
|
||||
future: ?std.Io.Future(@typeInfo(@typeInfo(@TypeOf(run)).@"fn".return_type.?).error_union.error_set!void) = null,
|
||||
termios: ?posix.termios = null,
|
||||
handler_registered: bool = false,
|
||||
@@ -147,16 +145,26 @@ pub fn App(comptime M: type, comptime E: type) type {
|
||||
future.cancel(this.io) catch {};
|
||||
this.future = null;
|
||||
}
|
||||
// reset stdin nonblocking reading
|
||||
{
|
||||
// Step 1: Get current flags
|
||||
var fl_flags = posix.system.fcntl(posix.STDIN_FILENO, posix.F.GETFL, 0);
|
||||
// Step 2: Remove O_NONBLOCK
|
||||
fl_flags ^= 1 << @bitOffsetOf(posix.system.O, "NONBLOCK");
|
||||
// std.log.debug("end fl_flags: {any}", .{fl_flags});
|
||||
// Step 3: Set new flags
|
||||
_ = posix.system.fcntl(posix.STDIN_FILENO, posix.F.SETFL, fl_flags);
|
||||
}
|
||||
}
|
||||
|
||||
/// Quit the application loop.
|
||||
/// This will cancel the internal input thread and post a **.quit** `Event`.
|
||||
pub fn quit(this: *@This()) !void {
|
||||
try this.postEvent(.quit);
|
||||
if (this.future) |*future| {
|
||||
future.cancel(this.io) catch {};
|
||||
this.future = null;
|
||||
}
|
||||
try this.postEvent(.quit);
|
||||
}
|
||||
|
||||
/// Returns the next available event, blocking until one is available.
|
||||
@@ -169,14 +177,22 @@ pub fn App(comptime M: type, comptime E: type) type {
|
||||
try this.queue.push(this.io, e);
|
||||
}
|
||||
|
||||
pub fn yankToSystemClipboard(this: *@This(), w: *std.Io.Writer, gpa: Allocator, str: []const u8) !void {
|
||||
_ = this;
|
||||
try terminal.yankToSystemClipboard(w, gpa, str);
|
||||
}
|
||||
|
||||
fn run(this: *@This()) !void {
|
||||
// thread to read user inputs
|
||||
var buf: [512]u8 = undefined;
|
||||
// NOTE set the `NONBLOCK` option for the stdin file, such that reading is not blocking!
|
||||
if (this.config.rawMode) {
|
||||
// if (this.config.rawMode) {
|
||||
{
|
||||
// TODO is there a better way to do this through the `std.Io` interface?
|
||||
var fl_flags = posix.system.fcntl(posix.STDIN_FILENO, posix.F.GETFL, 0);
|
||||
// std.log.debug("start fl_flags: {any}", .{fl_flags});
|
||||
fl_flags |= 1 << @bitOffsetOf(posix.system.O, "NONBLOCK");
|
||||
// std.log.debug("setting of fl_flags: {any}", .{fl_flags});
|
||||
_ = posix.system.fcntl(posix.STDIN_FILENO, posix.F.SETFL, fl_flags);
|
||||
}
|
||||
|
||||
|
||||
+3
-10
@@ -159,16 +159,6 @@ pub const Direct = struct {
|
||||
try terminal.clearScreen();
|
||||
}
|
||||
|
||||
pub fn writeCtrlDWithNewline(this: *@This(), writer: *std.Io.Writer) !void {
|
||||
_ = this;
|
||||
_ = try terminal.write(writer, "^D\n");
|
||||
}
|
||||
|
||||
pub fn writeNewline(this: *@This(), writer: *std.Io.Writer) !void {
|
||||
_ = this;
|
||||
_ = try terminal.write(writer, "\n");
|
||||
}
|
||||
|
||||
/// Render provided cells at size (anchor and dimension) into the *screen*.
|
||||
pub fn render(this: *@This(), comptime Container: type, container: *Container, comptime Model: type, model: *const Model) !void {
|
||||
const size: Point = container.size;
|
||||
@@ -218,6 +208,7 @@ pub const Direct = struct {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if there is nothing more to draw we can simply end this row rendering and go to the next row
|
||||
if (last_cell) {
|
||||
//std.log.debug("Found the last cell in row: {d} at column: {d}", .{row, col});
|
||||
_ = try writer.write("\n");
|
||||
@@ -227,6 +218,8 @@ pub const Direct = struct {
|
||||
try cvs.value(writer);
|
||||
if (cvs.style.cursor) return; // that's where the cursor should be left!
|
||||
}
|
||||
// write newline at the end of the row
|
||||
_ = try writer.write("\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -63,6 +63,17 @@ pub fn ringBell(w: *std.Io.Writer) !void {
|
||||
_ = try w.write(&.{7});
|
||||
}
|
||||
|
||||
pub fn yankToSystemClipboard(w: *std.Io.Writer, gpa: Allocator, str: []const u8) !void {
|
||||
const encoder: std.base64.Base64Encoder = .init(std.base64.url_safe_alphabet_chars, '=');
|
||||
const encoded_str: []u8 = try gpa.alloc(u8, encoder.calcSize(str.len));
|
||||
defer gpa.free(encoded_str);
|
||||
_ = encoder.encode(encoded_str, str);
|
||||
// NOTE for `tmux` support it should be configured to pass through the escape sequence for OSC52
|
||||
const value = try std.fmt.allocPrint(gpa, ctlseqs.osc52_clipboard_copy, .{encoded_str});
|
||||
defer gpa.free(value);
|
||||
try w.writeAll(value);
|
||||
}
|
||||
|
||||
pub fn read(buf: []u8) !usize {
|
||||
return try posix.read(posix.STDIN_FILENO, buf);
|
||||
}
|
||||
@@ -227,6 +238,7 @@ const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const posix = std.posix;
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = mem.Allocator;
|
||||
const ctlseqs = @import("ctlseqs.zig");
|
||||
const input = @import("input.zig");
|
||||
const Key = input.Key;
|
||||
|
||||
Reference in New Issue
Block a user