blob: d6913d407c02c27ef264806ce0662fa8ca8e7c8c [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 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
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020021#define BalloonEval int /* used in header files */
Bram Moolenaar423f9722010-10-10 17:08:43 +020022
Bram Moolenaar164fca32010-07-14 13:58:07 +020023#include "vim.h"
24#import <Cocoa/Cocoa.h>
25
26
Bram Moolenaare00289d2010-08-14 21:56:42 +020027/*
28 * Clipboard support for the console.
29 * Don't include this when building the GUI version, the functions in
Bram Moolenaar10d46642010-08-15 12:57:37 +020030 * gui_mac.c are used then. TODO: remove those instead?
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020031 * But for MacVim we do need these ones.
Bram Moolenaare00289d2010-08-14 21:56:42 +020032 */
Bram Moolenaar9a4d7fd2011-06-13 02:04:00 +020033#if defined(FEAT_CLIPBOARD) && (!defined(FEAT_GUI_ENABLED) || defined(FEAT_GUI_MACVIM))
Bram Moolenaar164fca32010-07-14 13:58:07 +020034
Bram Moolenaar66bd1c92010-07-14 20:31:44 +020035/* Used to identify clipboard data copied from Vim. */
36
37NSString *VimPboardType = @"VimPboardType";
38
Bram Moolenaar164fca32010-07-14 13:58:07 +020039 void
Bram Moolenaar448a2252016-01-31 18:08:34 +010040clip_mch_lose_selection(VimClipboard *cbd UNUSED)
Bram Moolenaar164fca32010-07-14 13:58:07 +020041{
42}
43
44
45 int
Bram Moolenaar448a2252016-01-31 18:08:34 +010046clip_mch_own_selection(VimClipboard *cbd UNUSED)
Bram Moolenaar164fca32010-07-14 13:58:07 +020047{
48 /* This is called whenever there is a new selection and 'guioptions'
49 * contains the "a" flag (automatically copy selection). Return TRUE, else
50 * the "a" flag does nothing. Note that there is no concept of "ownership"
51 * of the clipboard in Mac OS X.
52 */
53 return TRUE;
54}
55
56
57 void
58clip_mch_request_selection(VimClipboard *cbd)
59{
60 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
61
62 NSPasteboard *pb = [NSPasteboard generalPasteboard];
63 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
64 NSStringPboardType, nil];
65 NSString *bestType = [pb availableTypeFromArray:supportedTypes];
66 if (!bestType) goto releasepool;
67
Bram Moolenaar54b08a52011-06-20 00:25:44 +020068 int motion_type = MAUTO;
Bram Moolenaar164fca32010-07-14 13:58:07 +020069 NSString *string = nil;
70
71 if ([bestType isEqual:VimPboardType])
72 {
73 /* This type should consist of an array with two objects:
74 * 1. motion type (NSNumber)
75 * 2. text (NSString)
76 * If this is not the case we fall back on using NSStringPboardType.
77 */
78 id plist = [pb propertyListForType:VimPboardType];
79 if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2)
80 {
81 id obj = [plist objectAtIndex:1];
82 if ([obj isKindOfClass:[NSString class]])
83 {
84 motion_type = [[plist objectAtIndex:0] intValue];
85 string = obj;
86 }
87 }
88 }
89
90 if (!string)
91 {
Bram Moolenaar54b08a52011-06-20 00:25:44 +020092 /* Use NSStringPboardType. The motion type is detected automatically.
Bram Moolenaar164fca32010-07-14 13:58:07 +020093 */
94 NSMutableString *mstring =
95 [[pb stringForType:NSStringPboardType] mutableCopy];
96 if (!mstring) goto releasepool;
97
98 /* Replace unrecognized end-of-line sequences with \x0a (line feed). */
99 NSRange range = { 0, [mstring length] };
100 unsigned n = [mstring replaceOccurrencesOfString:@"\x0d\x0a"
101 withString:@"\x0a" options:0
102 range:range];
103 if (0 == n)
104 {
105 n = [mstring replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
106 options:0 range:range];
107 }
Bram Moolenaard43848c2010-07-14 14:28:26 +0200108
Bram Moolenaar164fca32010-07-14 13:58:07 +0200109 string = mstring;
110 }
111
Bram Moolenaar54b08a52011-06-20 00:25:44 +0200112 /* Default to MAUTO, uses MCHAR or MLINE depending on trailing NL. */
Bram Moolenaar164fca32010-07-14 13:58:07 +0200113 if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
114 || MAUTO == motion_type))
Bram Moolenaar54b08a52011-06-20 00:25:44 +0200115 motion_type = MAUTO;
Bram Moolenaar164fca32010-07-14 13:58:07 +0200116
117 char_u *str = (char_u*)[string UTF8String];
118 int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
119
120#ifdef FEAT_MBYTE
121 if (input_conv.vc_type != CONV_NONE)
122 str = string_convert(&input_conv, str, &len);
123#endif
124
125 if (str)
126 clip_yank_selection(motion_type, str, len, cbd);
127
128#ifdef FEAT_MBYTE
129 if (input_conv.vc_type != CONV_NONE)
130 vim_free(str);
131#endif
132
133releasepool:
134 [pool release];
135}
136
137
138/*
139 * Send the current selection to the clipboard.
140 */
141 void
142clip_mch_set_selection(VimClipboard *cbd)
143{
144 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
145
146 /* If the '*' register isn't already filled in, fill it in now. */
147 cbd->owned = TRUE;
148 clip_get_selection(cbd);
149 cbd->owned = FALSE;
Bram Moolenaard43848c2010-07-14 14:28:26 +0200150
Bram Moolenaar164fca32010-07-14 13:58:07 +0200151 /* Get the text to put on the pasteboard. */
152 long_u llen = 0; char_u *str = 0;
153 int motion_type = clip_convert_selection(&str, &llen, cbd);
154 if (motion_type < 0)
155 goto releasepool;
156
157 /* TODO: Avoid overflow. */
158 int len = (int)llen;
159#ifdef FEAT_MBYTE
160 if (output_conv.vc_type != CONV_NONE)
161 {
162 char_u *conv_str = string_convert(&output_conv, str, &len);
163 if (conv_str)
164 {
165 vim_free(str);
166 str = conv_str;
167 }
168 }
169#endif
170
171 if (len > 0)
172 {
173 NSString *string = [[NSString alloc]
174 initWithBytes:str length:len encoding:NSUTF8StringEncoding];
175
176 /* See clip_mch_request_selection() for info on pasteboard types. */
177 NSPasteboard *pb = [NSPasteboard generalPasteboard];
178 NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
179 NSStringPboardType, nil];
180 [pb declareTypes:supportedTypes owner:nil];
181
182 NSNumber *motion = [NSNumber numberWithInt:motion_type];
183 NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
184 [pb setPropertyList:plist forType:VimPboardType];
185
186 [pb setString:string forType:NSStringPboardType];
Bram Moolenaard43848c2010-07-14 14:28:26 +0200187
Bram Moolenaar164fca32010-07-14 13:58:07 +0200188 [string release];
189 }
190
191 vim_free(str);
192releasepool:
193 [pool release];
194}
195
196#endif /* FEAT_CLIPBOARD */