blob: 029f103b1a747a032f16d5aaa80530581623328f [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
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 Moolenaard0573012017-10-28 21:11:06 +020011 * os_macosx.m -- Mac specific things for Mac OS X.
Bram Moolenaar071d4272004-06-13 20:20:40 +000012 */
13
Bram Moolenaar423f9722010-10-10 17:08:43 +020014/* Avoid a conflict for the definition of Boolean between Mac header files and
15 * X11 header files. */
16#define NO_X11_INCLUDES
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020017#define BalloonEval int /* used in header files */
Bram Moolenaar423f9722010-10-10 17:08:43 +020018
Bram Moolenaar164fca32010-07-14 13:58:07 +020019#include "vim.h"
Bram Moolenaard0573012017-10-28 21:11:06 +020020#import <AppKit/AppKit.h>
Bram Moolenaar164fca32010-07-14 13:58:07 +020021
22
Bram Moolenaare00289d2010-08-14 21:56:42 +020023/*
24 * Clipboard support for the console.
25 * Don't include this when building the GUI version, the functions in
Bram Moolenaar10d46642010-08-15 12:57:37 +020026 * gui_mac.c are used then. TODO: remove those instead?
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020027 * But for MacVim we do need these ones.
Bram Moolenaare00289d2010-08-14 21:56:42 +020028 */
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020029#if defined(FEAT_CLIPBOARD) && (!defined(FEAT_GUI_ENABLED) || defined(FEAT_GUI_MACVIM))
Bram Moolenaar164fca32010-07-14 13:58:07 +020030
Bram Moolenaar66bd1c92010-07-14 20:31:44 +020031/* Used to identify clipboard data copied from Vim. */
32
33NSString *VimPboardType = @"VimPboardType";
34
Bram Moolenaar164fca32010-07-14 13:58:07 +020035 void
Bram Moolenaar448a2252016-01-31 18:08:34 +010036clip_mch_lose_selection(VimClipboard *cbd UNUSED)
Bram Moolenaar164fca32010-07-14 13:58:07 +020037{
38}
39
40
41 int
Bram Moolenaar448a2252016-01-31 18:08:34 +010042clip_mch_own_selection(VimClipboard *cbd UNUSED)
Bram Moolenaar164fca32010-07-14 13:58:07 +020043{
44 /* This is called whenever there is a new selection and 'guioptions'
45 * contains the "a" flag (automatically copy selection). Return TRUE, else
46 * the "a" flag does nothing. Note that there is no concept of "ownership"
47 * of the clipboard in Mac OS X.
48 */
49 return TRUE;
50}
51
52
53 void
54clip_mch_request_selection(VimClipboard *cbd)
55{
56 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
57
58 NSPasteboard *pb = [NSPasteboard generalPasteboard];
59 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
60 NSStringPboardType, nil];
61 NSString *bestType = [pb availableTypeFromArray:supportedTypes];
62 if (!bestType) goto releasepool;
63
Bram Moolenaar54b08a52011-06-20 00:25:44 +020064 int motion_type = MAUTO;
Bram Moolenaar164fca32010-07-14 13:58:07 +020065 NSString *string = nil;
66
67 if ([bestType isEqual:VimPboardType])
68 {
69 /* This type should consist of an array with two objects:
70 * 1. motion type (NSNumber)
71 * 2. text (NSString)
72 * If this is not the case we fall back on using NSStringPboardType.
73 */
74 id plist = [pb propertyListForType:VimPboardType];
75 if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2)
76 {
77 id obj = [plist objectAtIndex:1];
78 if ([obj isKindOfClass:[NSString class]])
79 {
80 motion_type = [[plist objectAtIndex:0] intValue];
81 string = obj;
82 }
83 }
84 }
85
86 if (!string)
87 {
Bram Moolenaar54b08a52011-06-20 00:25:44 +020088 /* Use NSStringPboardType. The motion type is detected automatically.
Bram Moolenaar164fca32010-07-14 13:58:07 +020089 */
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 string = mstring;
106 }
107
Bram Moolenaar54b08a52011-06-20 00:25:44 +0200108 /* Default to MAUTO, uses MCHAR or MLINE depending on trailing NL. */
Bram Moolenaar164fca32010-07-14 13:58:07 +0200109 if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
110 || MAUTO == motion_type))
Bram Moolenaar54b08a52011-06-20 00:25:44 +0200111 motion_type = MAUTO;
Bram Moolenaar164fca32010-07-14 13:58:07 +0200112
113 char_u *str = (char_u*)[string UTF8String];
114 int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
115
116#ifdef FEAT_MBYTE
117 if (input_conv.vc_type != CONV_NONE)
118 str = string_convert(&input_conv, str, &len);
119#endif
120
121 if (str)
122 clip_yank_selection(motion_type, str, len, cbd);
123
124#ifdef FEAT_MBYTE
125 if (input_conv.vc_type != CONV_NONE)
126 vim_free(str);
127#endif
128
129releasepool:
130 [pool release];
131}
132
133
134/*
135 * Send the current selection to the clipboard.
136 */
137 void
138clip_mch_set_selection(VimClipboard *cbd)
139{
140 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
141
142 /* If the '*' register isn't already filled in, fill it in now. */
143 cbd->owned = TRUE;
144 clip_get_selection(cbd);
145 cbd->owned = FALSE;
Bram Moolenaard43848c2010-07-14 14:28:26 +0200146
Bram Moolenaar164fca32010-07-14 13:58:07 +0200147 /* Get the text to put on the pasteboard. */
148 long_u llen = 0; char_u *str = 0;
149 int motion_type = clip_convert_selection(&str, &llen, cbd);
150 if (motion_type < 0)
151 goto releasepool;
152
153 /* TODO: Avoid overflow. */
154 int len = (int)llen;
155#ifdef FEAT_MBYTE
156 if (output_conv.vc_type != CONV_NONE)
157 {
158 char_u *conv_str = string_convert(&output_conv, str, &len);
159 if (conv_str)
160 {
161 vim_free(str);
162 str = conv_str;
163 }
164 }
165#endif
166
167 if (len > 0)
168 {
169 NSString *string = [[NSString alloc]
170 initWithBytes:str length:len encoding:NSUTF8StringEncoding];
171
172 /* See clip_mch_request_selection() for info on pasteboard types. */
173 NSPasteboard *pb = [NSPasteboard generalPasteboard];
174 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
175 NSStringPboardType, nil];
176 [pb declareTypes:supportedTypes owner:nil];
177
178 NSNumber *motion = [NSNumber numberWithInt:motion_type];
179 NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
180 [pb setPropertyList:plist forType:VimPboardType];
181
182 [pb setString:string forType:NSStringPboardType];
Bram Moolenaard43848c2010-07-14 14:28:26 +0200183
Bram Moolenaar164fca32010-07-14 13:58:07 +0200184 [string release];
185 }
186
187 vim_free(str);
188releasepool:
189 [pool release];
190}
191
192#endif /* FEAT_CLIPBOARD */