use cocoa::base::id;use cocoa::foundation::NSRange;use objc::{class, msg_send, sel, sel_impl}; /// The `cocoa` crate does not define NSAttributedString (and related Cocoa classes),/// which are needed for copying rich text (that is, text intermingled with images)/// to the clipboard. This adds access to those APIs.#[allow(non_snake_case)]pub trait NSAttributedString: Sized { unsafe fn alloc(_: Self) -> id { msg_send![class!(NSAttributedString), alloc] } unsafe fn init_attributed_string(self, string: id) -> id; unsafe fn appendAttributedString_(self, attr_string: id); unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id; unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id; unsafe fn string(self) -> id;} impl NSAttributedString for id { unsafe fn init_attributed_string(self, string: id) -> id { msg_send![self, initWithString: string] } unsafe fn appendAttributedString_(self, attr_string: id) { let _: () = msg_send![self, appendAttributedString: attr_string]; } unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id { msg_send![self, RTFDFromRange: range documentAttributes: attrs] } unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id { msg_send![self, RTFFromRange: range documentAttributes: attrs] } unsafe fn string(self) -> id { msg_send![self, string] }} pub trait NSMutableAttributedString: NSAttributedString { unsafe fn alloc(_: Self) -> id { msg_send![class!(NSMutableAttributedString), alloc] }} impl NSMutableAttributedString for id {} #[cfg(test)]mod tests { use super::*; use cocoa::appkit::NSImage; use cocoa::base::nil; use cocoa::foundation::NSString; #[test] #[ignore] // This was SIGSEGV-ing on CI but not locally; need to investigate https://github.com/zed-industries/zed/actions/runs/10362363230/job/28684225486?pr=15782#step:4:1348 fn test_nsattributed_string() { // TODO move these to parent module once it's actually ready to be used #[allow(non_snake_case)] pub trait NSTextAttachment: Sized { unsafe fn alloc(_: Self) -> id { msg_send![class!(NSTextAttachment), alloc] } } impl NSTextAttachment for id {} unsafe { let image: id = msg_send![class!(NSImage), alloc]; image.initWithContentsOfFile_(NSString::alloc(nil).init_str("test.jpeg")); let _size = image.size(); let string = NSString::alloc(nil).init_str("Test String"); let attr_string = NSMutableAttributedString::alloc(nil).init_attributed_string(string); let hello_string = NSString::alloc(nil).init_str("Hello World"); let hello_attr_string = NSAttributedString::alloc(nil).init_attributed_string(hello_string); attr_string.appendAttributedString_(hello_attr_string); let attachment = NSTextAttachment::alloc(nil); let _: () = msg_send![attachment, setImage: image]; let image_attr_string = msg_send![class!(NSAttributedString), attributedStringWithAttachment: attachment]; attr_string.appendAttributedString_(image_attr_string); let another_string = NSString::alloc(nil).init_str("Another String"); let another_attr_string = NSAttributedString::alloc(nil).init_attributed_string(another_string); attr_string.appendAttributedString_(another_attr_string); let _len: cocoa::foundation::NSUInteger = msg_send![attr_string, length]; /////////////////////////////////////////////////// // pasteboard.clearContents(); let rtfd_data = attr_string.RTFDFromRange_documentAttributes_( NSRange::new(0, msg_send![attr_string, length]), nil, ); assert_ne!(rtfd_data, nil); // if rtfd_data != nil { // pasteboard.setData_forType(rtfd_data, NSPasteboardTypeRTFD); // } // let rtf_data = attributed_string.RTFFromRange_documentAttributes_( // NSRange::new(0, attributed_string.length()), // nil, // ); // if rtf_data != nil { // pasteboard.setData_forType(rtf_data, NSPasteboardTypeRTF); // } // let plain_text = attributed_string.string(); // pasteboard.setString_forType(plain_text, NSPasteboardTypeString); } }}
use cocoa::base::id;
use cocoa::foundation::NSRange;
use objc::{class, msg_send, sel, sel_impl};
/// The `cocoa` crate does not define NSAttributedString (and related Cocoa classes),
/// which are needed for copying rich text (that is, text intermingled with images)
/// to the clipboard. This adds access to those APIs.
#[allow(non_snake_case)]
pub trait NSAttributedString: Sized {
unsafe fn alloc(_: Self) -> id {
msg_send![class!(NSAttributedString), alloc]
}
unsafe fn init_attributed_string(self, string: id) -> id;
unsafe fn appendAttributedString_(self, attr_string: id);
unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id;
unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id;
unsafe fn string(self) -> id;
}
impl NSAttributedString for id {
unsafe fn init_attributed_string(self, string: id) -> id {
msg_send![self, initWithString: string]
}
unsafe fn appendAttributedString_(self, attr_string: id) {
let _: () = msg_send![self, appendAttributedString: attr_string];
}
unsafe fn RTFDFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id {
msg_send![self, RTFDFromRange: range documentAttributes: attrs]
}
unsafe fn RTFFromRange_documentAttributes_(self, range: NSRange, attrs: id) -> id {
msg_send![self, RTFFromRange: range documentAttributes: attrs]
}
unsafe fn string(self) -> id {
msg_send![self, string]
}
}
pub trait NSMutableAttributedString: NSAttributedString {
unsafe fn alloc(_: Self) -> id {
msg_send![class!(NSMutableAttributedString), alloc]
}
}
impl NSMutableAttributedString for id {}
#[cfg(test)]
mod tests {
use super::*;
use cocoa::appkit::NSImage;
use cocoa::base::nil;
use cocoa::foundation::NSString;
#[test]
#[ignore] // This was SIGSEGV-ing on CI but not locally; need to investigate https://github.com/zed-industries/zed/actions/runs/10362363230/job/28684225486?pr=15782#step:4:1348
fn test_nsattributed_string() {
// TODO move these to parent module once it's actually ready to be used
#[allow(non_snake_case)]
pub trait NSTextAttachment: Sized {
unsafe fn alloc(_: Self) -> id {
msg_send![class!(NSTextAttachment), alloc]
}
}
impl NSTextAttachment for id {}
unsafe {
let image: id = msg_send![class!(NSImage), alloc];
image.initWithContentsOfFile_(NSString::alloc(nil).init_str("test.jpeg"));
let _size = image.size();
let string = NSString::alloc(nil).init_str("Test String");
let attr_string = NSMutableAttributedString::alloc(nil).init_attributed_string(string);
let hello_string = NSString::alloc(nil).init_str("Hello World");
let hello_attr_string =
NSAttributedString::alloc(nil).init_attributed_string(hello_string);
attr_string.appendAttributedString_(hello_attr_string);
let attachment = NSTextAttachment::alloc(nil);
let _: () = msg_send![attachment, setImage: image];
let image_attr_string =
msg_send![class!(NSAttributedString), attributedStringWithAttachment: attachment];
attr_string.appendAttributedString_(image_attr_string);
let another_string = NSString::alloc(nil).init_str("Another String");
let another_attr_string =
NSAttributedString::alloc(nil).init_attributed_string(another_string);
attr_string.appendAttributedString_(another_attr_string);
let _len: cocoa::foundation::NSUInteger = msg_send![attr_string, length];
///////////////////////////////////////////////////
// pasteboard.clearContents();
let rtfd_data = attr_string.RTFDFromRange_documentAttributes_(
NSRange::new(0, msg_send![attr_string, length]),
nil,
);
assert_ne!(rtfd_data, nil);
// if rtfd_data != nil {
// pasteboard.setData_forType(rtfd_data, NSPasteboardTypeRTFD);
// }
// let rtf_data = attributed_string.RTFFromRange_documentAttributes_(
// NSRange::new(0, attributed_string.length()),
// nil,
// );
// if rtf_data != nil {
// pasteboard.setData_forType(rtf_data, NSPasteboardTypeRTF);
// }
// let plain_text = attributed_string.string();
// pasteboard.setString_forType(plain_text, NSPasteboardTypeString);
}
}
}