39
|
1 /* vi:set ts=8 sts=4 sw=4:
|
|
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 #ifndef MACOS_X_UNIX
|
|
15 Error: MACOS 9 is no longer supported in Vim 7
|
|
16 #endif
|
|
17
|
|
18 /* Avoid a conflict for the definition of Boolean between Mac header files and
|
|
19 * X11 header files. */
|
|
20 #define NO_X11_INCLUDES
|
|
21
|
|
22 #include "vim.h"
|
|
23 #import <Cocoa/Cocoa.h>
|
|
24
|
|
25
|
|
26 /*
|
|
27 * Clipboard support for the console.
|
|
28 * Don't include this when building the GUI version, the functions in
|
|
29 * gui_mac.c are used then. TODO: remove those instead?
|
|
30 * But for MacVim we need these ones.
|
|
31 */
|
|
32 #if defined(FEAT_CLIPBOARD) && (!defined(FEAT_GUI) || defined(FEAT_GUI_MACVIM))
|
|
33
|
|
34 /* Used to identify clipboard data copied from Vim. */
|
|
35
|
|
36 NSString *VimPboardType = @"VimPboardType";
|
|
37
|
|
38 void
|
|
39 clip_mch_lose_selection(VimClipboard *cbd)
|
|
40 {
|
|
41 }
|
|
42
|
|
43
|
|
44 int
|
|
45 clip_mch_own_selection(VimClipboard *cbd)
|
|
46 {
|
|
47 /* This is called whenever there is a new selection and 'guioptions'
|
|
48 * contains the "a" flag (automatically copy selection). Return TRUE, else
|
|
49 * the "a" flag does nothing. Note that there is no concept of "ownership"
|
|
50 * of the clipboard in Mac OS X.
|
|
51 */
|
|
52 return TRUE;
|
|
53 }
|
|
54
|
|
55
|
|
56 void
|
|
57 clip_mch_request_selection(VimClipboard *cbd)
|
|
58 {
|
|
59 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
60
|
|
61 NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
|
62 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
|
|
63 NSStringPboardType, nil];
|
|
64 NSString *bestType = [pb availableTypeFromArray:supportedTypes];
|
|
65 if (!bestType) goto releasepool;
|
|
66
|
|
67 int motion_type = MCHAR;
|
|
68 NSString *string = nil;
|
|
69
|
|
70 if ([bestType isEqual:VimPboardType])
|
|
71 {
|
|
72 /* This type should consist of an array with two objects:
|
|
73 * 1. motion type (NSNumber)
|
|
74 * 2. text (NSString)
|
|
75 * If this is not the case we fall back on using NSStringPboardType.
|
|
76 */
|
|
77 id plist = [pb propertyListForType:VimPboardType];
|
|
78 if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2)
|
|
79 {
|
|
80 id obj = [plist objectAtIndex:1];
|
|
81 if ([obj isKindOfClass:[NSString class]])
|
|
82 {
|
|
83 motion_type = [[plist objectAtIndex:0] intValue];
|
|
84 string = obj;
|
|
85 }
|
|
86 }
|
|
87 }
|
|
88
|
|
89 if (!string)
|
|
90 {
|
|
91 /* Use NSStringPboardType. The motion type is set to line-wise if the
|
|
92 * string contains at least one EOL character, otherwise it is set to
|
|
93 * character-wise (block-wise is never used).
|
|
94 */
|
|
95 NSMutableString *mstring =
|
|
96 [[pb stringForType:NSStringPboardType] mutableCopy];
|
|
97 if (!mstring) goto releasepool;
|
|
98
|
|
99 /* Replace unrecognized end-of-line sequences with \x0a (line feed). */
|
|
100 NSRange range = { 0, [mstring length] };
|
|
101 unsigned n = [mstring replaceOccurrencesOfString:@"\x0d\x0a"
|
|
102 withString:@"\x0a" options:0
|
|
103 range:range];
|
|
104 if (0 == n)
|
|
105 {
|
|
106 n = [mstring replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
|
|
107 options:0 range:range];
|
|
108 }
|
|
109
|
|
110 /* Scan for newline character to decide whether the string should be
|
|
111 * pasted line-wise or character-wise.
|
|
112 */
|
|
113 motion_type = MCHAR;
|
|
114 if (0 < n || NSNotFound != [mstring rangeOfString:@"\n"].location)
|
|
115 motion_type = MLINE;
|
|
116
|
|
117 string = mstring;
|
|
118 }
|
|
119
|
|
120 if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
|
|
121 || MAUTO == motion_type))
|
|
122 motion_type = MCHAR;
|
|
123
|
|
124 char_u *str = (char_u*)[string UTF8String];
|
|
125 int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
|
126
|
|
127 #ifdef FEAT_MBYTE
|
|
128 if (input_conv.vc_type != CONV_NONE)
|
|
129 str = string_convert(&input_conv, str, &len);
|
|
130 #endif
|
|
131
|
|
132 if (str)
|
|
133 clip_yank_selection(motion_type, str, len, cbd);
|
|
134
|
|
135 #ifdef FEAT_MBYTE
|
|
136 if (input_conv.vc_type != CONV_NONE)
|
|
137 vim_free(str);
|
|
138 #endif
|
|
139
|
|
140 releasepool:
|
|
141 [pool release];
|
|
142 }
|
|
143
|
|
144
|
|
145 /*
|
|
146 * Send the current selection to the clipboard.
|
|
147 */
|
|
148 void
|
|
149 clip_mch_set_selection(VimClipboard *cbd)
|
|
150 {
|
|
151 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
152
|
|
153 /* If the '*' register isn't already filled in, fill it in now. */
|
|
154 cbd->owned = TRUE;
|
|
155 clip_get_selection(cbd);
|
|
156 cbd->owned = FALSE;
|
|
157
|
|
158 /* Get the text to put on the pasteboard. */
|
|
159 long_u llen = 0; char_u *str = 0;
|
|
160 int motion_type = clip_convert_selection(&str, &llen, cbd);
|
|
161 if (motion_type < 0)
|
|
162 goto releasepool;
|
|
163
|
|
164 /* TODO: Avoid overflow. */
|
|
165 int len = (int)llen;
|
|
166 #ifdef FEAT_MBYTE
|
|
167 if (output_conv.vc_type != CONV_NONE)
|
|
168 {
|
|
169 char_u *conv_str = string_convert(&output_conv, str, &len);
|
|
170 if (conv_str)
|
|
171 {
|
|
172 vim_free(str);
|
|
173 str = conv_str;
|
|
174 }
|
|
175 }
|
|
176 #endif
|
|
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];
|
|
185 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
|
|
186 NSStringPboardType, nil];
|
|
187 [pb declareTypes:supportedTypes owner:nil];
|
|
188
|
|
189 NSNumber *motion = [NSNumber numberWithInt:motion_type];
|
|
190 NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
|
|
191 [pb setPropertyList:plist forType:VimPboardType];
|
|
192
|
|
193 [pb setString:string forType:NSStringPboardType];
|
|
194
|
|
195 [string release];
|
|
196 }
|
|
197
|
|
198 vim_free(str);
|
|
199 releasepool:
|
|
200 [pool release];
|
|
201 }
|
|
202
|
|
203 #endif /* FEAT_CLIPBOARD */
|