90449001082063701b076d0365d6d94be88429b6
[MacVim.git] / src / MacVim / MacVim.m
blob90449001082063701b076d0365d6d94be88429b6
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     "ZoomMsgID",
97     "END OF MESSAGE IDs"     // NOTE: Must be last!
103 NSString *MMLogLevelKey     = @"MMLogLevel";
104 NSString *MMLogToStdErrKey  = @"MMLogToStdErr";
106 // Argument used to stop MacVim from opening an empty window on startup
107 // (techincally this is a user default but should not be used as such).
108 NSString *MMNoWindowKey = @"MMNoWindow";
110 NSString *MMAutosaveRowsKey    = @"MMAutosaveRows";
111 NSString *MMAutosaveColumnsKey = @"MMAutosaveColumns";
112 NSString *MMRendererKey        = @"MMRenderer";
114 // Vim pasteboard type (holds motion type + string)
115 NSString *VimPboardType = @"VimPboardType";
116 // Vim find pasteboard type (string contains Vim regex patterns)
117 NSString *VimFindPboardType = @"VimFindPboardType";
119 int ASLogLevel = ASL_LEVEL_NOTICE;
123 // Create a string holding the labels of all messages in message queue for
124 // debugging purposes (condense some messages since there may typically be LOTS
125 // of them on a queue).
126     NSString *
127 debugStringForMessageQueue(NSArray *queue)
129     NSMutableString *s = [NSMutableString new];
130     unsigned i, count = [queue count];
131     int item = 0, menu = 0, enable = 0, remove = 0;
132     int sets = 0, sett = 0, shows = 0, cres = 0, dess = 0;
133     for (i = 0; i < count; i += 2) {
134         NSData *value = [queue objectAtIndex:i];
135         int msgid = *((int*)[value bytes]);
136         if (msgid < 1 || msgid >= LastMsgID)
137             continue;
138         if (msgid == AddMenuItemMsgID) ++item;
139         else if (msgid == AddMenuMsgID) ++menu;
140         else if (msgid == EnableMenuItemMsgID) ++enable;
141         else if (msgid == RemoveMenuItemMsgID) ++remove;
142         else if (msgid == SetScrollbarPositionMsgID) ++sets;
143         else if (msgid == SetScrollbarThumbMsgID) ++sett;
144         else if (msgid == ShowScrollbarMsgID) ++shows;
145         else if (msgid == CreateScrollbarMsgID) ++cres;
146         else if (msgid == DestroyScrollbarMsgID) ++dess;
147         else [s appendFormat:@"%s ", MessageStrings[msgid]];
148     }
149     if (item > 0) [s appendFormat:@"AddMenuItemMsgID(%d) ", item];
150     if (menu > 0) [s appendFormat:@"AddMenuMsgID(%d) ", menu];
151     if (enable > 0) [s appendFormat:@"EnableMenuItemMsgID(%d) ", enable];
152     if (remove > 0) [s appendFormat:@"RemoveMenuItemMsgID(%d) ", remove];
153     if (sets > 0) [s appendFormat:@"SetScrollbarPositionMsgID(%d) ", sets];
154     if (sett > 0) [s appendFormat:@"SetScrollbarThumbMsgID(%d) ", sett];
155     if (shows > 0) [s appendFormat:@"ShowScrollbarMsgID(%d) ", shows];
156     if (cres > 0) [s appendFormat:@"CreateScrollbarMsgID(%d) ", cres];
157     if (dess > 0) [s appendFormat:@"DestroyScrollbarMsgID(%d) ", dess];
159     return [s autorelease];
165 @implementation NSString (MMExtras)
167 - (NSString *)stringByEscapingSpecialFilenameCharacters
169     // NOTE: This code assumes that no characters already have been escaped.
170     NSMutableString *string = [self mutableCopy];
172     [string replaceOccurrencesOfString:@"\\"
173                             withString:@"\\\\"
174                                options:NSLiteralSearch
175                                  range:NSMakeRange(0, [string length])];
176     [string replaceOccurrencesOfString:@" "
177                             withString:@"\\ "
178                                options:NSLiteralSearch
179                                  range:NSMakeRange(0, [string length])];
180     [string replaceOccurrencesOfString:@"\t"
181                             withString:@"\\\t "
182                                options:NSLiteralSearch
183                                  range:NSMakeRange(0, [string length])];
184     [string replaceOccurrencesOfString:@"%"
185                             withString:@"\\%"
186                                options:NSLiteralSearch
187                                  range:NSMakeRange(0, [string length])];
188     [string replaceOccurrencesOfString:@"#"
189                             withString:@"\\#"
190                                options:NSLiteralSearch
191                                  range:NSMakeRange(0, [string length])];
192     [string replaceOccurrencesOfString:@"|"
193                             withString:@"\\|"
194                                options:NSLiteralSearch
195                                  range:NSMakeRange(0, [string length])];
196     [string replaceOccurrencesOfString:@"\""
197                             withString:@"\\\""
198                                options:NSLiteralSearch
199                                  range:NSMakeRange(0, [string length])];
201     return [string autorelease];
204 - (NSString *)stringByRemovingFindPatterns
206     // Remove some common patterns added to search strings that other apps are
207     // not aware of.
209     NSMutableString *string = [self mutableCopy];
211     // Added when doing * search
212     [string replaceOccurrencesOfString:@"\\<"
213                             withString:@""
214                                options:NSLiteralSearch
215                                  range:NSMakeRange(0, [string length])];
216     [string replaceOccurrencesOfString:@"\\>"
217                             withString:@""
218                                options:NSLiteralSearch
219                                  range:NSMakeRange(0, [string length])];
220     // \V = match whole word
221     [string replaceOccurrencesOfString:@"\\V"
222                             withString:@""
223                                options:NSLiteralSearch
224                                  range:NSMakeRange(0, [string length])];
225     // \c = case insensitive, \C = case sensitive
226     [string replaceOccurrencesOfString:@"\\c"
227                             withString:@""
228                                options:NSCaseInsensitiveSearch|NSLiteralSearch
229                                  range:NSMakeRange(0, [string length])];
231     return [string autorelease];
234 @end // NSString (MMExtras)
238 @implementation NSColor (MMExtras)
240 + (NSColor *)colorWithRgbInt:(unsigned)rgb
242     float r = ((rgb>>16) & 0xff)/255.0f;
243     float g = ((rgb>>8) & 0xff)/255.0f;
244     float b = (rgb & 0xff)/255.0f;
246     return [NSColor colorWithDeviceRed:r green:g blue:b alpha:1.0f];
249 + (NSColor *)colorWithArgbInt:(unsigned)argb
251     float a = ((argb>>24) & 0xff)/255.0f;
252     float r = ((argb>>16) & 0xff)/255.0f;
253     float g = ((argb>>8) & 0xff)/255.0f;
254     float b = (argb & 0xff)/255.0f;
256     return [NSColor colorWithDeviceRed:r green:g blue:b alpha:a];
259 @end // NSColor (MMExtras)
264 @implementation NSDictionary (MMExtras)
266 + (id)dictionaryWithData:(NSData *)data
268     id plist = [NSPropertyListSerialization
269             propertyListFromData:data
270                 mutabilityOption:NSPropertyListImmutable
271                           format:NULL
272                 errorDescription:NULL];
274     return [plist isKindOfClass:[NSDictionary class]] ? plist : nil;
277 - (NSData *)dictionaryAsData
279     return [NSPropertyListSerialization dataFromPropertyList:self
280             format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];
283 @end
288 @implementation NSMutableDictionary (MMExtras)
290 + (id)dictionaryWithData:(NSData *)data
292     id plist = [NSPropertyListSerialization
293             propertyListFromData:data
294                 mutabilityOption:NSPropertyListMutableContainers
295                           format:NULL
296                 errorDescription:NULL];
298     return [plist isKindOfClass:[NSMutableDictionary class]] ? plist : nil;
301 @end
306     void
307 ASLInit()
309     NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
311     // Allow for changing the log level via user defaults.  If no key is found
312     // the default log level will be used (which for ASL is to log everything
313     // up to ASL_LEVEL_NOTICE).  This key is an integer which corresponds to
314     // the ASL_LEVEL_* macros (0 is most severe, 7 is debug level).
315     id logLevelObj = [ud objectForKey:MMLogLevelKey];
316     if (logLevelObj) {
317         int logLevel = [logLevelObj intValue];
318         if (logLevel < 0) logLevel = 0;
319         if (logLevel > ASL_LEVEL_DEBUG) logLevel = ASL_LEVEL_DEBUG;
321         ASLogLevel = logLevel;
322         asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(logLevel));
323     }
325     // Allow for changing whether a copy of each log should be sent to stderr
326     // (this defaults to NO if this key is missing in the user defaults
327     // database).  The above filter mask is applied to logs going to stderr,
328     // contrary to how "vanilla" ASL works.
329     BOOL logToStdErr = [ud boolForKey:MMLogToStdErrKey];
330     if (logToStdErr)
331         asl_add_log_file(NULL, 2);  // The file descriptor for stderr is 2