blob: 1d88e7dcd69f1914f044ca376d5c8d40b6bdd801 [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 Moolenaar423f9722010-10-10 17:08:43 +020018/* Avoid a conflict for the definition of Boolean between Mac header files and
19 * X11 header files. */
20#define NO_X11_INCLUDES
21
Bram Moolenaar164fca32010-07-14 13:58:07 +020022#include "vim.h"
23#import <Cocoa/Cocoa.h>
24
25
Bram Moolenaare00289d2010-08-14 21:56:42 +020026/*
27 * Clipboard support for the console.
28 * Don't include this when building the GUI version, the functions in
Bram Moolenaar10d46642010-08-15 12:57:37 +020029 * gui_mac.c are used then. TODO: remove those instead?
30 * But for MacVim we need these ones.
Bram Moolenaare00289d2010-08-14 21:56:42 +020031 */
Bram Moolenaar10d46642010-08-15 12:57:37 +020032#if defined(FEAT_CLIPBOARD) && (!defined(FEAT_GUI) || defined(FEAT_GUI_MACVIM))
Bram Moolenaar164fca32010-07-14 13:58:07 +020033
Bram Moolenaar66bd1c92010-07-14 20:31:44 +020034/* Used to identify clipboard data copied from Vim. */
35
36NSString *VimPboardType = @"VimPboardType";
37
Bram Moolenaar164fca32010-07-14 13:58:07 +020038 void
39clip_mch_lose_selection(VimClipboard *cbd)
40{
41}
42
43
44 int
45clip_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
57clip_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 }
Bram Moolenaard43848c2010-07-14 14:28:26 +0200109
Bram Moolenaar164fca32010-07-14 13:58:07 +0200110 /* 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
140releasepool:
141 [pool release];
142}
143
144
145/*
146 * Send the current selection to the clipboard.
147 */
148 void
149clip_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;
Bram Moolenaard43848c2010-07-14 14:28:26 +0200157
Bram Moolenaar164fca32010-07-14 13:58:07 +0200158 /* 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];
Bram Moolenaard43848c2010-07-14 14:28:26 +0200194
Bram Moolenaar164fca32010-07-14 13:58:07 +0200195 [string release];
196 }
197
198 vim_free(str);
199releasepool:
200 [pool release];
201}
202
203#endif /* FEAT_CLIPBOARD */