diff --git a/build.zig b/build.zig index 242a70c..cb43d76 100644 --- a/build.zig +++ b/build.zig @@ -23,6 +23,21 @@ pub fn build(b: *std.Build) void { }), }); + if (target.result.os.tag == .macos) { + exe.root_module.addCSourceFiles(.{ + .files = &.{"src/Clip/NSPBBridge.m"}, + .language = .objective_c, + .flags = &.{"-fobjc-arc"}, + }); + exe.root_module.linkFramework("Cocoa", .{}); + tests.root_module.addCSourceFiles(.{ + .files = &.{"src/Clip/NSPBBridge.m"}, + .language = .objective_c, + .flags = &.{"-fobjc-arc"}, + }); + tests.root_module.linkFramework("Cocoa", .{}); + } + const test_step = b.step("test", "Run tests"); const run_tests = b.addRunArtifact(tests); test_step.dependOn(&run_tests.step); diff --git a/src/Clip.zig b/src/Clip.zig index 8d264c8..1adeeb0 100644 --- a/src/Clip.zig +++ b/src/Clip.zig @@ -1,4 +1,5 @@ pub const OSC52 = @import("Clip/OSC52.zig"); +// pub const PBCopy = if (@import("builtin").os.tag == .macos) @import("Clip/OSC52.zig") else null; // I am not sure if this is super idiomatic Zig or if this is bad practice, but // by ensuring that all Clip backends implement the same methods, we are able @@ -15,6 +16,8 @@ fn assertFn(comptime T: type, comptime name: []const u8, comptime Sig: type) voi } test { + _ = @import("Clip/NSPasteBoard.zig"); + inline for (@typeInfo(@This()).@"struct".decls) |decl| { // Only grab types of structs const T = @field(@This(), decl.name); diff --git a/src/Clip/NSPBBridge.m b/src/Clip/NSPBBridge.m new file mode 100644 index 0000000..e736c3f --- /dev/null +++ b/src/Clip/NSPBBridge.m @@ -0,0 +1,12 @@ +// Simple bridge to objective_c code +// https://nathancraddock.com/blog/writing-to-the-clipboard-the-hard-way/ +#import +NSPasteboard *pboard; + +void initPB() { pboard = [NSPasteboard generalPasteboard]; } + +void sendPB(const char *text) { + [pboard clearContents]; + [pboard setString:[NSString stringWithUTF8String:text] + forType:NSPasteboardTypeString]; +} diff --git a/src/Clip/NSPasteboard.zig b/src/Clip/NSPasteboard.zig new file mode 100644 index 0000000..92c3403 --- /dev/null +++ b/src/Clip/NSPasteboard.zig @@ -0,0 +1,18 @@ +const std = @import("std"); + +extern fn sendPB(text: [*:0]const u8) void; +extern fn initPB() void; + +test "objc bridge" { + initPB(); + sendPB("test_string"); + + const result = try std.process.run(std.testing.allocator, std.testing.io, .{ + .argv = &.{"pbpaste"}, + }); + defer std.testing.allocator.free(result.stdout); + defer std.testing.allocator.free(result.stderr); + + try std.testing.expectEqualStrings("test_string", std.mem.trim(u8, result.stdout, "\n")); +} +