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