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);
|
try std.io.getStdErr().writer().writeAll(result.stderr);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
.Exited => |code| if (code != 0) return error.NonZeroExit,
|
.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 {
|
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);
|
defer allocator.free(xclip_cmd);
|
||||||
|
std.log.debug("cmd: {s}", .{xclip_cmd});
|
||||||
|
|
||||||
return std.ChildProcess.exec(.{
|
return std.ChildProcess.exec(.{
|
||||||
.allocator = allocator,
|
.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 {
|
fn execWindows(allocator: std.mem.Allocator, data: []const u8) !std.ChildProcess.ExecResult {
|
||||||
const clip_cmd = try std.fmt.allocPrint(allocator, "echo '{s}'| clip", .{data});
|
// we need to do this (maybe) because there is no real way to close stdin cleanly, which is what will
|
||||||
defer allocator.free(clip_cmd);
|
// 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(.{
|
return std.ChildProcess.exec(.{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.argv = &[_][]const u8{
|
.argv = &[_][]const u8{
|
||||||
"c:\\windows\\system32\\cmd.exe", // TODO: use Comspec
|
"powershell",
|
||||||
"/c",
|
"-Command",
|
||||||
clip_cmd,
|
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