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