Skip to content

Commit 0103383

Browse files
committed
core: normalize newlines in non-bracketed pastes
Fixes #547 For non-bracketed paste mode, "\r\n" => "\r" and "\n" => "\r". See the issue for more supporting documentation.
1 parent 7cb5c51 commit 0103383

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

src/Surface.zig

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,20 +2202,48 @@ fn completeClipboardPaste(self: *Surface, data: []const u8) !void {
22022202
};
22032203

22042204
if (bracketed) {
2205+
// If we're bracketd we write the data as-is to the terminal with
2206+
// the bracketed paste escape codes around it.
22052207
_ = self.io_thread.mailbox.push(.{
22062208
.write_stable = "\x1B[200~",
22072209
}, .{ .forever = {} });
2208-
}
2209-
2210-
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
2211-
self.alloc,
2212-
data,
2213-
), .{ .forever = {} });
2214-
2215-
if (bracketed) {
2210+
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
2211+
self.alloc,
2212+
data,
2213+
), .{ .forever = {} });
22162214
_ = self.io_thread.mailbox.push(.{
22172215
.write_stable = "\x1B[201~",
22182216
}, .{ .forever = {} });
2217+
} else {
2218+
// If its not bracketed the input bytes are indistinguishable from
2219+
// keystrokes, so we must be careful. For example, we must replace
2220+
// any newlines with '\r'.
2221+
2222+
// We just do a heap allocation here because its easy and I don't think
2223+
// worth the optimization of using small messages.
2224+
var buf = try self.alloc.alloc(u8, data.len);
2225+
defer self.alloc.free(buf);
2226+
2227+
// This is super, super suboptimal. We can easily make use of SIMD
2228+
// here, but maybe LLVM in release mode is smart enough to figure
2229+
// out something clever. Either way, large non-bracketed pastes are
2230+
// increasingly rare for modern applications.
2231+
var len: usize = 0;
2232+
for (data, 0..) |ch, i| {
2233+
const dch = switch (ch) {
2234+
'\n' => '\r',
2235+
'\r' => if (i + 1 < data.len and data[i + 1] == '\n') continue else ch,
2236+
else => ch,
2237+
};
2238+
2239+
buf[len] = dch;
2240+
len += 1;
2241+
}
2242+
2243+
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
2244+
self.alloc,
2245+
buf[0..len],
2246+
), .{ .forever = {} });
22192247
}
22202248

22212249
try self.io_thread.wakeup.notify();

0 commit comments

Comments
 (0)