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