xref: /vim-8.2.3635/src/os_macosx.m (revision 2bf24176)
1/* 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/*
11 * os_macosx.m -- Mac specific things for Mac OS/X.
12 */
13
14#ifndef MACOS_X_UNIX
15    Error: MACOS 9 is no longer supported in Vim 7
16#endif
17
18/* Avoid a conflict for the definition of Boolean between Mac header files and
19 * X11 header files. */
20#define NO_X11_INCLUDES
21#define BalloonEval int   /* used in header files */
22
23#include "vim.h"
24#import <Cocoa/Cocoa.h>
25
26
27/*
28 * Clipboard support for the console.
29 * Don't include this when building the GUI version, the functions in
30 * gui_mac.c are used then.  TODO: remove those instead?
31 * But for MacVim we do need these ones.
32 */
33#if defined(FEAT_CLIPBOARD) && (!defined(FEAT_GUI_ENABLED) || defined(FEAT_GUI_MACVIM))
34
35/* Used to identify clipboard data copied from Vim. */
36
37NSString *VimPboardType = @"VimPboardType";
38
39    void
40clip_mch_lose_selection(VimClipboard *cbd)
41{
42}
43
44
45    int
46clip_mch_own_selection(VimClipboard *cbd)
47{
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
68    int motion_type = MAUTO;
69    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    {
92	/* Use NSStringPboardType.  The motion type is detected automatically.
93	 */
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	}
108
109	string = mstring;
110    }
111
112    /* Default to MAUTO, uses MCHAR or MLINE depending on trailing NL. */
113    if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
114	    || MAUTO == motion_type))
115	motion_type = MAUTO;
116
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;
150
151    /* 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];
187
188	[string release];
189    }
190
191    vim_free(str);
192releasepool:
193    [pool release];
194}
195
196#endif /* FEAT_CLIPBOARD */
197