1/* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10/* 11 * os_macosx.m -- Mac specific things for Mac OS X. 12 */ 13 14/* Suppress compiler warnings to non-C89 code. */ 15#if defined(__clang__) && defined(__STRICT_ANSI__) 16# pragma clang diagnostic push 17# pragma clang diagnostic ignored "-Wc99-extensions" 18# pragma clang diagnostic push 19# pragma clang diagnostic ignored "-Wdeclaration-after-statement" 20#endif 21 22/* Avoid a conflict for the definition of Boolean between Mac header files and 23 * X11 header files. */ 24#define NO_X11_INCLUDES 25 26#include "vim.h" 27#import <AppKit/AppKit.h> 28 29 30/* 31 * Clipboard support for the console. 32 */ 33#if defined(FEAT_CLIPBOARD) 34 35/* Used to identify clipboard data copied from Vim. */ 36 37NSString *VimPboardType = @"VimPboardType"; 38 39 void 40clip_mch_lose_selection(Clipboard_T *cbd UNUSED) 41{ 42} 43 44 45 int 46clip_mch_own_selection(Clipboard_T *cbd UNUSED) 47{ 48 /* This is called whenever there is a new selection and 'guioptions' 49 * contains the "a" flag (automatically copy selection). Return TRUE, else 50 * the "a" flag does nothing. Note that there is no concept of "ownership" 51 * of the clipboard in Mac OS X. 52 */ 53 return TRUE; 54} 55 56 57 void 58clip_mch_request_selection(Clipboard_T *cbd) 59{ 60 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 61 62 NSPasteboard *pb = [NSPasteboard generalPasteboard]; 63#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 64 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType, 65 NSPasteboardTypeString, nil]; 66#else 67 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType, 68 NSStringPboardType, nil]; 69#endif 70 NSString *bestType = [pb availableTypeFromArray:supportedTypes]; 71 if (!bestType) goto releasepool; 72 73 int motion_type = MAUTO; 74 NSString *string = nil; 75 76 if ([bestType isEqual:VimPboardType]) 77 { 78 /* This type should consist of an array with two objects: 79 * 1. motion type (NSNumber) 80 * 2. text (NSString) 81 * If this is not the case we fall back on using NSPasteboardTypeString. 82 */ 83 id plist = [pb propertyListForType:VimPboardType]; 84 if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2) 85 { 86 id obj = [plist objectAtIndex:1]; 87 if ([obj isKindOfClass:[NSString class]]) 88 { 89 motion_type = [[plist objectAtIndex:0] intValue]; 90 string = obj; 91 } 92 } 93 } 94 95 if (!string) 96 { 97 /* Use NSPasteboardTypeString. The motion type is detected automatically. 98 */ 99#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 100 NSMutableString *mstring = 101 [[pb stringForType:NSPasteboardTypeString] mutableCopy]; 102#else 103 NSMutableString *mstring = 104 [[pb stringForType:NSStringPboardType] mutableCopy]; 105#endif 106 if (!mstring) goto releasepool; 107 108 /* Replace unrecognized end-of-line sequences with \x0a (line feed). */ 109 NSRange range = { 0, [mstring length] }; 110 unsigned n = [mstring replaceOccurrencesOfString:@"\x0d\x0a" 111 withString:@"\x0a" options:0 112 range:range]; 113 if (0 == n) 114 { 115 n = [mstring replaceOccurrencesOfString:@"\x0d" withString:@"\x0a" 116 options:0 range:range]; 117 } 118 119 string = mstring; 120 } 121 122 /* Default to MAUTO, uses MCHAR or MLINE depending on trailing NL. */ 123 if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type 124 || MAUTO == motion_type)) 125 motion_type = MAUTO; 126 127 char_u *str = (char_u*)[string UTF8String]; 128 int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 129 130 if (input_conv.vc_type != CONV_NONE) 131 str = string_convert(&input_conv, str, &len); 132 133 if (str) 134 clip_yank_selection(motion_type, str, len, cbd); 135 136 if (input_conv.vc_type != CONV_NONE) 137 vim_free(str); 138 139releasepool: 140 [pool release]; 141} 142 143 144/* 145 * Send the current selection to the clipboard. 146 */ 147 void 148clip_mch_set_selection(Clipboard_T *cbd) 149{ 150 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 151 152 /* If the '*' register isn't already filled in, fill it in now. */ 153 cbd->owned = TRUE; 154 clip_get_selection(cbd); 155 cbd->owned = FALSE; 156 157 /* Get the text to put on the pasteboard. */ 158 long_u llen = 0; char_u *str = 0; 159 int motion_type = clip_convert_selection(&str, &llen, cbd); 160 if (motion_type < 0) 161 goto releasepool; 162 163 /* TODO: Avoid overflow. */ 164 int len = (int)llen; 165 if (output_conv.vc_type != CONV_NONE) 166 { 167 char_u *conv_str = string_convert(&output_conv, str, &len); 168 if (conv_str) 169 { 170 vim_free(str); 171 str = conv_str; 172 } 173 } 174 175 if (len > 0) 176 { 177 NSString *string = [[NSString alloc] 178 initWithBytes:str length:len encoding:NSUTF8StringEncoding]; 179 180 /* See clip_mch_request_selection() for info on pasteboard types. */ 181 NSPasteboard *pb = [NSPasteboard generalPasteboard]; 182#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 183 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType, 184 NSPasteboardTypeString, nil]; 185#else 186 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType, 187 NSStringPboardType, nil]; 188#endif 189 [pb declareTypes:supportedTypes owner:nil]; 190 191 NSNumber *motion = [NSNumber numberWithInt:motion_type]; 192 NSArray *plist = [NSArray arrayWithObjects:motion, string, nil]; 193 [pb setPropertyList:plist forType:VimPboardType]; 194 195#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 196 [pb setString:string forType:NSPasteboardTypeString]; 197#else 198 [pb setString:string forType:NSStringPboardType]; 199#endif 200 201 [string release]; 202 } 203 204 vim_free(str); 205releasepool: 206 [pool release]; 207} 208 209#endif /* FEAT_CLIPBOARD */ 210 211/* Lift the compiler warning suppression. */ 212#if defined(__clang__) && defined(__STRICT_ANSI__) 213# pragma clang diagnostic pop 214# pragma clang diagnostic pop 215#endif 216