implement clipboard set, both windows and linux
This commit is contained in:
		
							parent
							
								
									113fb5e75c
								
							
						
					
					
						commit
						a2a6302588
					
				
					 1 changed files with 44 additions and 6 deletions
				
			
		|  | @ -56,6 +56,7 @@ fn addToClipboard(allocator: std.mem.Allocator, data: []const u8) !void { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     std.log.debug("exec done", .{}); | ||||
|     try std.io.getStdErr().writer().writeAll(result.stderr); | ||||
|     switch (result.term) { | ||||
|         .Exited => |code| if (code != 0) return error.NonZeroExit, | ||||
|  | @ -66,8 +67,17 @@ fn addToClipboard(allocator: std.mem.Allocator, data: []const u8) !void { | |||
| } | ||||
| 
 | ||||
| fn execLinux(allocator: std.mem.Allocator, data: []const u8) !std.ChildProcess.ExecResult { | ||||
|     const xclip_cmd = try std.fmt.allocPrint(allocator, "echo -n '{s}'| xclip -selection c", .{data}); | ||||
|     // we need to do this (maybe) because there is no real way to close stdin cleanly, which is what will | ||||
|     // kill xclip. | ||||
|     // | ||||
|     // Also, it seems xclip doesn't close stdout, which triggers ChildProcess.exec to know | ||||
|     // that the process is done. Redirecting stdout/stderr as below will get the job | ||||
|     // done, though | ||||
|     const escaped_data = try escape(allocator, data, "'", "'\"", "\"'"); | ||||
|     defer allocator.free(escaped_data); | ||||
|     const xclip_cmd = try std.fmt.allocPrint(allocator, "echo -n '{s}'| xclip -selection c >/dev/null 2>&1", .{escaped_data}); | ||||
|     defer allocator.free(xclip_cmd); | ||||
|     std.log.debug("cmd: {s}", .{xclip_cmd}); | ||||
| 
 | ||||
|     return std.ChildProcess.exec(.{ | ||||
|         .allocator = allocator, | ||||
|  | @ -81,15 +91,43 @@ fn execLinux(allocator: std.mem.Allocator, data: []const u8) !std.ChildProcess.E | |||
| } | ||||
| 
 | ||||
| fn execWindows(allocator: std.mem.Allocator, data: []const u8) !std.ChildProcess.ExecResult { | ||||
|     const clip_cmd = try std.fmt.allocPrint(allocator, "echo '{s}'| clip", .{data}); | ||||
|     defer allocator.free(clip_cmd); | ||||
|     // we need to do this (maybe) because there is no real way to close stdin cleanly, which is what will | ||||
|     // kill clip.exe | ||||
|     // TODO: Create minimal repro and submit zig stdlib bug | ||||
|     const escaped_data = try escape(allocator, data, "'", "'", ""); | ||||
|     defer allocator.free(escaped_data); | ||||
|     const cmd = try std.fmt.allocPrint(allocator, "write-output '{s}'| set-clipboard", .{escaped_data}); | ||||
|     defer allocator.free(cmd); | ||||
|     std.log.debug("cmd: {s}", .{cmd}); | ||||
| 
 | ||||
|     return std.ChildProcess.exec(.{ | ||||
|         .allocator = allocator, | ||||
|         .argv = &[_][]const u8{ | ||||
|             "c:\\windows\\system32\\cmd.exe", // TODO: use Comspec | ||||
|             "/c", | ||||
|             clip_cmd, | ||||
|             "powershell", | ||||
|             "-Command", | ||||
|             cmd, | ||||
|         }, | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| fn escape(allocator: std.mem.Allocator, data: []const u8, danger_chars: []const u8, prefix: []const u8, suffix: []const u8) ![]const u8 { | ||||
|     var escaped = try std.ArrayList(u8).initCapacity(allocator, data.len); | ||||
|     defer escaped.deinit(); | ||||
|     for (data) |c| { | ||||
|         var needs_escape = false; | ||||
|         for (danger_chars) |dc| { | ||||
|             if (c == dc) { | ||||
|                 needs_escape = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (needs_escape) { | ||||
|             try escaped.appendSlice(prefix); | ||||
|             try escaped.append(c); | ||||
|             try escaped.appendSlice(suffix); | ||||
|         } else { | ||||
|             try escaped.append(c); | ||||
|         } | ||||
|     } | ||||
|     return escaped.toOwnedSlice(); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue