@@ -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