implement clipboard set, both windows and linux
This commit is contained in:
parent
113fb5e75c
commit
a2a6302588
|
@ -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…
Reference in New Issue
Block a user