Improve Find pasteboard interaction
[MacVim.git] / src / MacVim / MacVim.m
blob06748c638bdba03744a3e61bff866864d5ce33af
1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
2  *
3  * VIM - Vi IMproved            by Bram Moolenaar
4  *                              MacVim GUI port by Bjorn Winckler
5  *
6  * Do ":help uganda"  in Vim to read copying and usage conditions.
7  * Do ":help credits" in Vim to see a list of people who contributed.
8  * See README.txt for an overview of the Vim source code.
9  */
11  * MacVim.m:  Code shared between Vim and MacVim.
12  */
14 #import "MacVim.h"
17 char *MessageStrings[] = 
19     "INVALID MESSAGE ID",
20     "OpenWindowMsgID",
21     "KeyDownMsgID",
22     "BatchDrawMsgID",
23     "SelectTabMsgID",
24     "CloseTabMsgID",
25     "AddNewTabMsgID",
26     "DraggedTabMsgID",
27     "UpdateTabBarMsgID",
28     "ShowTabBarMsgID",
29     "HideTabBarMsgID",
30     "SetTextRowsMsgID",
31     "SetTextColumnsMsgID",
32     "SetTextDimensionsMsgID",
33     "LiveResizeMsgID",
34     "SetTextDimensionsReplyMsgID",
35     "SetWindowTitleMsgID",
36     "ScrollWheelMsgID",
37     "MouseDownMsgID",
38     "MouseUpMsgID",
39     "MouseDraggedMsgID",
40     "FlushQueueMsgID",
41     "AddMenuMsgID",
42     "AddMenuItemMsgID",
43     "RemoveMenuItemMsgID",
44     "EnableMenuItemMsgID",
45     "ExecuteMenuMsgID",
46     "ShowToolbarMsgID",
47     "ToggleToolbarMsgID",
48     "CreateScrollbarMsgID",
49     "DestroyScrollbarMsgID",
50     "ShowScrollbarMsgID",
51     "SetScrollbarPositionMsgID",
52     "SetScrollbarThumbMsgID",
53     "ScrollbarEventMsgID",
54     "SetFontMsgID",
55     "SetWideFontMsgID",
56     "VimShouldCloseMsgID",
57     "SetDefaultColorsMsgID",
58     "ExecuteActionMsgID",
59     "DropFilesMsgID",
60     "DropStringMsgID",
61     "ShowPopupMenuMsgID",
62     "GotFocusMsgID",
63     "LostFocusMsgID",
64     "MouseMovedMsgID",
65     "SetMouseShapeMsgID",
66     "AdjustLinespaceMsgID",
67     "ActivateMsgID",
68     "SetServerNameMsgID",
69     "EnterFullscreenMsgID",
70     "LeaveFullscreenMsgID",
71     "BuffersNotModifiedMsgID",
72     "BuffersModifiedMsgID",
73     "AddInputMsgID",
74     "SetPreEditPositionMsgID",
75     "TerminateNowMsgID",
76     "XcodeModMsgID",
77     "EnableAntialiasMsgID",
78     "DisableAntialiasMsgID",
79     "SetVimStateMsgID",
80     "SetDocumentFilenameMsgID",
81     "OpenWithArgumentsMsgID",
82     "CloseWindowMsgID",
83     "SetFullscreenColorMsgID",
84     "ShowFindReplaceDialogMsgID",
85     "FindReplaceMsgID",
86     "ActivateKeyScriptMsgID",
87     "DeactivateKeyScriptMsgID",
88     "EnableImControlMsgID",
89     "DisableImControlMsgID",
90     "ActivatedImMsgID",
91     "DeactivatedImMsgID",
92     "BrowseForFileMsgID",
93     "ShowDialogMsgID",
94     "NetBeansMsgID",
95     "SetMarkedTextMsgID",
96     "END OF MESSAGE IDs"     // NOTE: Must be last!
102 NSString *MMLogLevelKey     = @"MMLogLevel";
103 NSString *MMLogToStdErrKey  = @"MMLogToStdErr";
105 // Argument used to stop MacVim from opening an empty window on startup
106 // (techincally this is a user default but should not be used as such).
107 NSString *MMNoWindowKey = @"MMNoWindow";
109 NSString *MMAutosaveRowsKey    = @"MMAutosaveRows";
110 NSString *MMAutosaveColumnsKey = @"MMAutosaveColumns";
111 NSString *MMRendererKey        = @"MMRenderer";
113 // Vim pasteboard type (holds motion type + string)
114 NSString *VimPboardType = @"VimPboardType";
115 // Vim find pasteboard type (string contains Vim regex patterns)
116 NSString *VimFindPboardType = @"VimFindPboardType";
118 int ASLogLevel = ASL_LEVEL_NOTICE;
122 // Create a string holding the labels of all messages in message queue for
123 // debugging purposes (condense some messages since there may typically be LOTS
124 // of them on a queue).
125     NSString *
126 debugStringForMessageQueue(NSArray *queue)
128     NSMutableString *s = [NSMutableString new];
129     unsigned i, count = [queue count];
130     int item = 0, menu = 0, enable = 0, remove = 0;
131     int sets = 0, sett = 0, shows = 0, cres = 0, dess = 0;
132     for (i = 0; i < count; i += 2) {
133         NSData *value = [queue objectAtIndex:i];
134         int msgid = *((int*)[value bytes]);
135         if (msgid < 1 || msgid >= LastMsgID)
136             continue;
137         if (msgid == AddMenuItemMsgID) ++item;
138         else if (msgid == AddMenuMsgID) ++menu;
139         else if (msgid == EnableMenuItemMsgID) ++enable;
140         else if (msgid == RemoveMenuItemMsgID) ++remove;
141         else if (msgid == SetScrollbarPositionMsgID) ++sets;
142         else if (msgid == SetScrollbarThumbMsgID) ++sett;
143         else if (msgid == ShowScrollbarMsgID) ++shows;
144         else if (msgid == CreateScrollbarMsgID) ++cres;
145         else if (msgid == DestroyScrollbarMsgID) ++dess;
146         else [s appendFormat:@"%s ", MessageStrings[msgid]];
147     }
148     if (item > 0) [s appendFormat:@"AddMenuItemMsgID(%d) ", item];
149     if (menu > 0) [s appendFormat:@"AddMenuMsgID(%d) ", menu];
150     if (enable > 0) [s appendFormat:@"EnableMenuItemMsgID(%d) ", enable];
151     if (remove > 0) [s appendFormat:@"RemoveMenuItemMsgID(%d) ", remove];
152     if (sets > 0) [s appendFormat:@"SetScrollbarPositionMsgID(%d) ", sets];
153     if (sett > 0) [s appendFormat:@"SetScrollbarThumbMsgID(%d) ", sett];
154     if (shows > 0) [s appendFormat:@"ShowScrollbarMsgID(%d) ", shows];
155     if (cres > 0) [s appendFormat:@"CreateScrollbarMsgID(%d) ", cres];
156     if (dess > 0) [s appendFormat:@"DestroyScrollbarMsgID(%d) ", dess];
158     return [s autorelease];
164 @implementation NSString (MMExtras)
166 - (NSString *)stringByEscapingSpecialFilenameCharacters
168     // NOTE: This code assumes that no characters already have been escaped.
169     NSMutableString *string = [self mutableCopy];
171     [string replaceOccurrencesOfString:@"\\"
172                             withString:@"\\\\"
173                                options:NSLiteralSearch
174                                  range:NSMakeRange(0, [string length])];
175     [string replaceOccurrencesOfString:@" "
176                             withString:@"\\ "
177                                options:NSLiteralSearch
178                                  range:NSMakeRange(0, [string length])];
179     [string replaceOccurrencesOfString:@"\t"
180                             withString:@"\\\t "
181                                options:NSLiteralSearch
182                                  range:NSMakeRange(0, [string length])];
183     [string replaceOccurrencesOfString:@"%"
184                             withString:@"\\%"
185                                options:NSLiteralSearch
186                                  range:NSMakeRange(0, [string length])];
187     [string replaceOccurrencesOfString:@"#"
188                             withString:@"\\#"
189                                options:NSLiteralSearch
190                                  range:NSMakeRange(0, [string length])];
191     [string replaceOccurrencesOfString:@"|"
192                             withString:@"\\|"
193                                options:NSLiteralSearch
194                                  range:NSMakeRange(0, [string length])];
195     [string replaceOccurrencesOfString:@"\""
196                             withString:@"\\\""
197                                options:NSLiteralSearch
198                                  range:NSMakeRange(0, [string length])];
200     return [string autorelease];
203 - (NSString *)stringByRemovingFindPatterns
205     // Remove some common patterns added to search strings that other apps are
206     // not aware of.
208     NSMutableString *string = [self mutableCopy];
210     // Added when doing * search
211     [string replaceOccurrencesOfString:@"\\<"
212                             withString:@""
213                                options:NSLiteralSearch
214                                  range:NSMakeRange(0, [string length])];
215     [string replaceOccurrencesOfString:@"\\>"
216                             withString:@""
217                                options:NSLiteralSearch
218                                  range:NSMakeRange(0, [string length])];
219     // \V = match whole word
220     [string replaceOccurrencesOfString:@"\\V"
221                             withString:@""
222                                options:NSLiteralSearch
223                                  range:NSMakeRange(0, [string length])];
224     // \c = case insensitive, \C = case sensitive
225     [string replaceOccurrencesOfString:@"\\c"
226                             withString:@""
227                                options:NSCaseInsensitiveSearch|NSLiteralSearch
228                                  range:NSMakeRange(0, [string length])];
230     return [string autorelease];
233 @end // NSString (MMExtras)
237 @implementation NSColor (MMExtras)
239 + (NSColor *)colorWithRgbInt:(unsigned)rgb
241     float r = ((rgb>>16) & 0xff)/255.0f;
242     float g = ((rgb>>8) & 0xff)/255.0f;
243     float b = (rgb & 0xff)/255.0f;
245     return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0f];
248 + (NSColor *)colorWithArgbInt:(unsigned)argb
250     float a = ((argb>>24) & 0xff)/255.0f;
251     float r = ((argb>>16) & 0xff)/255.0f;
252     float g = ((argb>>8) & 0xff)/255.0f;
253     float b = (argb & 0xff)/255.0f;
255     return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a];
258 @end // NSColor (MMExtras)
263 @implementation NSDictionary (MMExtras)
265 + (id)dictionaryWithData:(NSData *)data
267     id plist = [NSPropertyListSerialization
268             propertyListFromData:data
269                 mutabilityOption:NSPropertyListImmutable
270                           format:NULL
271                 errorDescription:NULL];
273     return [plist isKindOfClass:[NSDictionary class]] ? plist : nil;
276 - (NSData *)dictionaryAsData
278     return [NSPropertyListSerialization dataFromPropertyList:self
279             format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];
282 @end
287 @implementation NSMutableDictionary (MMExtras)
289 + (id)dictionaryWithData:(NSData *)data
291     id plist = [NSPropertyListSerialization
292             propertyListFromData:data
293                 mutabilityOption:NSPropertyListMutableContainers
294                           format:NULL
295                 errorDescription:NULL];
297     return [plist isKindOfClass:[NSMutableDictionary class]] ? plist : nil;
300 @end
305     void
306 ASLInit()
308     NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
310     // Allow for changing the log level via user defaults.  If no key is found
311     // the default log level will be used (which for ASL is to log everything
312     // up to ASL_LEVEL_NOTICE).  This key is an integer which corresponds to
313     // the ASL_LEVEL_* macros (0 is most severe, 7 is debug level).
314     id logLevelObj = [ud objectForKey:MMLogLevelKey];
315     if (logLevelObj) {
316         int logLevel = [logLevelObj intValue];
317         if (logLevel < 0) logLevel = 0;
318         if (logLevel > ASL_LEVEL_DEBUG) logLevel = ASL_LEVEL_DEBUG;
320         ASLogLevel = logLevel;
321         asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(logLevel));
322     }
324     // Allow for changing whether a copy of each log should be sent to stderr
325     // (this defaults to NO if this key is missing in the user defaults
326     // database).  The above filter mask is applied to logs going to stderr,
327     // contrary to how "vanilla" ASL works.
328     BOOL logToStdErr = [ud boolForKey:MMLogToStdErrKey];
329     if (logToStdErr)
330         asl_add_log_file(NULL, 2);  // The file descriptor for stderr is 2