From d4c4330d4d7fea21112db63e61fa6766926bdfb3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 5 Aug 2022 11:37:02 -0700 Subject: [PATCH] copy! --- src/Window.zig | 66 ++++++++++++++++++++++++++++++----------- src/terminal/Screen.zig | 11 +++---- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/Window.zig b/src/Window.zig index a472a21d5..e4ad2fa59 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -448,28 +448,58 @@ fn keyCallback( _ = scancode; - // Paste - if (action == .press and mods.super and key == .v) { - const win = window.getUserPointer(Window) orelse return; + if (action == .press and mods.super) { + switch (key) { + // Copy + .c => { + const win = window.getUserPointer(Window) orelse return; - // Ignore this character for writing - win.ignore_char = true; + // Ignore this character for writing + win.ignore_char = true; - const data = glfw.getClipboardString() catch |err| { - log.warn("error reading clipboard: {}", .{err}); - return; - }; + // If we have a selection, copy it. + if (win.terminal.selection) |sel| { + var buf = win.terminal.screen.selectionString(win.alloc, sel) catch |err| { + log.err("error reading selection string err={}", .{err}); + return; + }; + defer win.alloc.free(buf); - if (data.len > 0) { - if (win.bracketed_paste) win.queueWrite("\x1B[200~") catch |err| - log.err("error queueing write in keyCallback err={}", .{err}); - win.queueWrite(data) catch |err| - log.warn("error pasting clipboard: {}", .{err}); - if (win.bracketed_paste) win.queueWrite("\x1B[201~") catch |err| - log.err("error queueing write in keyCallback err={}", .{err}); + glfw.setClipboardString(buf) catch |err| { + log.err("error setting clipboard string err={}", .{err}); + return; + }; + } + + return; + }, + + // Paste + .v => { + const win = window.getUserPointer(Window) orelse return; + + // Ignore this character for writing + win.ignore_char = true; + + const data = glfw.getClipboardString() catch |err| { + log.warn("error reading clipboard: {}", .{err}); + return; + }; + + if (data.len > 0) { + if (win.bracketed_paste) win.queueWrite("\x1B[200~") catch |err| + log.err("error queueing write in keyCallback err={}", .{err}); + win.queueWrite(data) catch |err| + log.warn("error pasting clipboard: {}", .{err}); + if (win.bracketed_paste) win.queueWrite("\x1B[201~") catch |err| + log.err("error queueing write in keyCallback err={}", .{err}); + } + + return; + }, + + else => {}, } - - return; } //log.info("KEY {} {} {} {}", .{ key, scancode, mods, action }); diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index b828898b1..e4fc6b247 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -402,7 +402,7 @@ pub fn resize(self: *Screen, alloc: Allocator, rows: usize, cols: usize) !void { /// Returns the raw text associated with a selection. This will unwrap /// soft-wrapped edges. The returned slice is owned by the caller. -pub fn selectionString(self: Screen, alloc: Allocator, sel: Selection) ![]const u8 { +pub fn selectionString(self: Screen, alloc: Allocator, sel: Selection) ![:0]const u8 { // Get the slices for the string const slices = self.selectionSlices(sel); @@ -424,7 +424,8 @@ pub fn selectionString(self: Screen, alloc: Allocator, sel: Selection) ![]const break :chars count; }; - const buf = try alloc.alloc(u8, chars + newlines); + const buf = try alloc.alloc(u8, chars + newlines + 1); + errdefer alloc.free(buf); var i: usize = 0; for (slices.top) |cell, idx| { @@ -465,9 +466,9 @@ pub fn selectionString(self: Screen, alloc: Allocator, sel: Selection) ![]const i += try std.unicode.utf8Encode(@intCast(u21, char), buf[i..]); } - // If we wrote less than what we allocated, try to shrink it. Otherwise - // return the buf as-is. - return if (i < buf.len) try alloc.realloc(buf, i) else buf; + // Add null termination + buf[i] = 0; + return buf[0..i :0]; } /// Returns the slices that make up the selection, in order. There are at most