feat(terminal): support OSC 52 to yank to system clipboard
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 14m56s
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 14m56s
Helper function for `App` which writes the necessary escape sequence directly to yank the provided string.
This commit is contained in:
+7
-1
@@ -1,5 +1,5 @@
|
|||||||
const QuitText = struct {
|
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 {
|
pub fn element(this: *@This()) App.Element {
|
||||||
return .{ .ptr = this, .vtable = &.{ .content = content } };
|
return .{ .ptr = this, .vtable = &.{ .content = content } };
|
||||||
@@ -150,6 +150,12 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
.key => |key| {
|
.key => |key| {
|
||||||
if (key.eql(.{ .cp = 'c', .mod = .{ .ctrl = true } })) try app.quit();
|
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 } })) {
|
if (key.eql(.{ .cp = 'n', .mod = .{ .ctrl = true } })) {
|
||||||
try app.stop(w);
|
try app.stop(w);
|
||||||
try w.flush();
|
try w.flush();
|
||||||
|
|||||||
@@ -177,6 +177,11 @@ pub fn App(comptime M: type, comptime E: type) type {
|
|||||||
try this.queue.push(this.io, e);
|
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 {
|
fn run(this: *@This()) !void {
|
||||||
// thread to read user inputs
|
// thread to read user inputs
|
||||||
var buf: [512]u8 = undefined;
|
var buf: [512]u8 = undefined;
|
||||||
|
|||||||
@@ -63,6 +63,17 @@ pub fn ringBell(w: *std.Io.Writer) !void {
|
|||||||
_ = try w.write(&.{7});
|
_ = 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 {
|
pub fn read(buf: []u8) !usize {
|
||||||
return try posix.read(posix.STDIN_FILENO, buf);
|
return try posix.read(posix.STDIN_FILENO, buf);
|
||||||
}
|
}
|
||||||
@@ -227,6 +238,7 @@ const std = @import("std");
|
|||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const posix = std.posix;
|
const posix = std.posix;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const Allocator = mem.Allocator;
|
||||||
const ctlseqs = @import("ctlseqs.zig");
|
const ctlseqs = @import("ctlseqs.zig");
|
||||||
const input = @import("input.zig");
|
const input = @import("input.zig");
|
||||||
const Key = input.Key;
|
const Key = input.Key;
|
||||||
|
|||||||
Reference in New Issue
Block a user