PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/MacVim/MacVim.m

https://github.com/Brijen/macvim
Objective C | 368 lines | 267 code | 63 blank | 38 comment | 49 complexity | 5ffbc404955ff28511504776dd1d7c23 MD5 | raw file
  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. */
  10. /*
  11. * MacVim.m: Code shared between Vim and MacVim.
  12. */
  13. #import "MacVim.h"
  14. char *MessageStrings[] =
  15. {
  16. "INVALID MESSAGE ID",
  17. "OpenWindowMsgID",
  18. "KeyDownMsgID",
  19. "BatchDrawMsgID",
  20. "SelectTabMsgID",
  21. "CloseTabMsgID",
  22. "AddNewTabMsgID",
  23. "DraggedTabMsgID",
  24. "UpdateTabBarMsgID",
  25. "ShowTabBarMsgID",
  26. "HideTabBarMsgID",
  27. "SetTextRowsMsgID",
  28. "SetTextColumnsMsgID",
  29. "SetTextDimensionsMsgID",
  30. "LiveResizeMsgID",
  31. "SetTextDimensionsReplyMsgID",
  32. "SetWindowTitleMsgID",
  33. "ScrollWheelMsgID",
  34. "MouseDownMsgID",
  35. "MouseUpMsgID",
  36. "MouseDraggedMsgID",
  37. "FlushQueueMsgID",
  38. "AddMenuMsgID",
  39. "AddMenuItemMsgID",
  40. "RemoveMenuItemMsgID",
  41. "EnableMenuItemMsgID",
  42. "ExecuteMenuMsgID",
  43. "ShowToolbarMsgID",
  44. "ToggleToolbarMsgID",
  45. "CreateScrollbarMsgID",
  46. "DestroyScrollbarMsgID",
  47. "ShowScrollbarMsgID",
  48. "SetScrollbarPositionMsgID",
  49. "SetScrollbarThumbMsgID",
  50. "ScrollbarEventMsgID",
  51. "SetFontMsgID",
  52. "SetWideFontMsgID",
  53. "VimShouldCloseMsgID",
  54. "SetDefaultColorsMsgID",
  55. "ExecuteActionMsgID",
  56. "DropFilesMsgID",
  57. "DropStringMsgID",
  58. "ShowPopupMenuMsgID",
  59. "GotFocusMsgID",
  60. "LostFocusMsgID",
  61. "MouseMovedMsgID",
  62. "SetMouseShapeMsgID",
  63. "AdjustLinespaceMsgID",
  64. "ActivateMsgID",
  65. "SetServerNameMsgID",
  66. "EnterFullScreenMsgID",
  67. "LeaveFullScreenMsgID",
  68. "SetBuffersModifiedMsgID",
  69. "AddInputMsgID",
  70. "SetPreEditPositionMsgID",
  71. "TerminateNowMsgID",
  72. "XcodeModMsgID",
  73. "EnableAntialiasMsgID",
  74. "DisableAntialiasMsgID",
  75. "SetVimStateMsgID",
  76. "SetDocumentFilenameMsgID",
  77. "OpenWithArgumentsMsgID",
  78. "CloseWindowMsgID",
  79. "SetFullScreenColorMsgID",
  80. "ShowFindReplaceDialogMsgID",
  81. "FindReplaceMsgID",
  82. "ActivateKeyScriptMsgID",
  83. "DeactivateKeyScriptMsgID",
  84. "EnableImControlMsgID",
  85. "DisableImControlMsgID",
  86. "ActivatedImMsgID",
  87. "DeactivatedImMsgID",
  88. "BrowseForFileMsgID",
  89. "ShowDialogMsgID",
  90. "NetBeansMsgID",
  91. "SetMarkedTextMsgID",
  92. "ZoomMsgID",
  93. "SetWindowPositionMsgID",
  94. "DeleteSignMsgID",
  95. "SetTooltipMsgID",
  96. "SetTooltipDelayMsgID",
  97. "GestureMsgID",
  98. "AddToMRUMsgID",
  99. "END OF MESSAGE IDs" // NOTE: Must be last!
  100. };
  101. NSString *MMLogLevelKey = @"MMLogLevel";
  102. NSString *MMLogToStdErrKey = @"MMLogToStdErr";
  103. // Argument used to stop MacVim from opening an empty window on startup
  104. // (techincally this is a user default but should not be used as such).
  105. NSString *MMNoWindowKey = @"MMNoWindow";
  106. NSString *MMAutosaveRowsKey = @"MMAutosaveRows";
  107. NSString *MMAutosaveColumnsKey = @"MMAutosaveColumns";
  108. NSString *MMRendererKey = @"MMRenderer";
  109. // Vim find pasteboard type (string contains Vim regex patterns)
  110. NSString *VimFindPboardType = @"VimFindPboardType";
  111. int ASLogLevel = ASL_LEVEL_NOTICE;
  112. // Create a string holding the labels of all messages in message queue for
  113. // debugging purposes (condense some messages since there may typically be LOTS
  114. // of them on a queue).
  115. NSString *
  116. debugStringForMessageQueue(NSArray *queue)
  117. {
  118. NSMutableString *s = [NSMutableString new];
  119. unsigned i, count = [queue count];
  120. int item = 0, menu = 0, enable = 0, remove = 0;
  121. int sets = 0, sett = 0, shows = 0, cres = 0, dess = 0;
  122. for (i = 0; i < count; i += 2) {
  123. NSData *value = [queue objectAtIndex:i];
  124. int msgid = *((int*)[value bytes]);
  125. if (msgid < 1 || msgid >= LastMsgID)
  126. continue;
  127. if (msgid == AddMenuItemMsgID) ++item;
  128. else if (msgid == AddMenuMsgID) ++menu;
  129. else if (msgid == EnableMenuItemMsgID) ++enable;
  130. else if (msgid == RemoveMenuItemMsgID) ++remove;
  131. else if (msgid == SetScrollbarPositionMsgID) ++sets;
  132. else if (msgid == SetScrollbarThumbMsgID) ++sett;
  133. else if (msgid == ShowScrollbarMsgID) ++shows;
  134. else if (msgid == CreateScrollbarMsgID) ++cres;
  135. else if (msgid == DestroyScrollbarMsgID) ++dess;
  136. else [s appendFormat:@"%s ", MessageStrings[msgid]];
  137. }
  138. if (item > 0) [s appendFormat:@"AddMenuItemMsgID(%d) ", item];
  139. if (menu > 0) [s appendFormat:@"AddMenuMsgID(%d) ", menu];
  140. if (enable > 0) [s appendFormat:@"EnableMenuItemMsgID(%d) ", enable];
  141. if (remove > 0) [s appendFormat:@"RemoveMenuItemMsgID(%d) ", remove];
  142. if (sets > 0) [s appendFormat:@"SetScrollbarPositionMsgID(%d) ", sets];
  143. if (sett > 0) [s appendFormat:@"SetScrollbarThumbMsgID(%d) ", sett];
  144. if (shows > 0) [s appendFormat:@"ShowScrollbarMsgID(%d) ", shows];
  145. if (cres > 0) [s appendFormat:@"CreateScrollbarMsgID(%d) ", cres];
  146. if (dess > 0) [s appendFormat:@"DestroyScrollbarMsgID(%d) ", dess];
  147. return [s autorelease];
  148. }
  149. @implementation NSString (MMExtras)
  150. - (NSString *)stringByEscapingSpecialFilenameCharacters
  151. {
  152. // NOTE: This code assumes that no characters already have been escaped.
  153. NSMutableString *string = [self mutableCopy];
  154. [string replaceOccurrencesOfString:@"\\"
  155. withString:@"\\\\"
  156. options:NSLiteralSearch
  157. range:NSMakeRange(0, [string length])];
  158. [string replaceOccurrencesOfString:@" "
  159. withString:@"\\ "
  160. options:NSLiteralSearch
  161. range:NSMakeRange(0, [string length])];
  162. [string replaceOccurrencesOfString:@"\t"
  163. withString:@"\\\t "
  164. options:NSLiteralSearch
  165. range:NSMakeRange(0, [string length])];
  166. [string replaceOccurrencesOfString:@"%"
  167. withString:@"\\%"
  168. options:NSLiteralSearch
  169. range:NSMakeRange(0, [string length])];
  170. [string replaceOccurrencesOfString:@"#"
  171. withString:@"\\#"
  172. options:NSLiteralSearch
  173. range:NSMakeRange(0, [string length])];
  174. [string replaceOccurrencesOfString:@"|"
  175. withString:@"\\|"
  176. options:NSLiteralSearch
  177. range:NSMakeRange(0, [string length])];
  178. [string replaceOccurrencesOfString:@"\""
  179. withString:@"\\\""
  180. options:NSLiteralSearch
  181. range:NSMakeRange(0, [string length])];
  182. return [string autorelease];
  183. }
  184. - (NSString *)stringByRemovingFindPatterns
  185. {
  186. // Remove some common patterns added to search strings that other apps are
  187. // not aware of.
  188. NSMutableString *string = [self mutableCopy];
  189. // Added when doing * search
  190. [string replaceOccurrencesOfString:@"\\<"
  191. withString:@""
  192. options:NSLiteralSearch
  193. range:NSMakeRange(0, [string length])];
  194. [string replaceOccurrencesOfString:@"\\>"
  195. withString:@""
  196. options:NSLiteralSearch
  197. range:NSMakeRange(0, [string length])];
  198. // \V = match whole word
  199. [string replaceOccurrencesOfString:@"\\V"
  200. withString:@""
  201. options:NSLiteralSearch
  202. range:NSMakeRange(0, [string length])];
  203. // \c = case insensitive, \C = case sensitive
  204. [string replaceOccurrencesOfString:@"\\c"
  205. withString:@""
  206. options:NSCaseInsensitiveSearch|NSLiteralSearch
  207. range:NSMakeRange(0, [string length])];
  208. return [string autorelease];
  209. }
  210. - (NSString *)stringBySanitizingSpotlightSearch
  211. {
  212. // Limit length of search text
  213. NSUInteger len = [self length];
  214. if (len > 1024) len = 1024;
  215. else if (len == 0) return self;
  216. NSMutableString *string = [[[self substringToIndex:len] mutableCopy]
  217. autorelease];
  218. // Ignore strings with control characters
  219. NSCharacterSet *controlChars = [NSCharacterSet controlCharacterSet];
  220. NSRange r = [string rangeOfCharacterFromSet:controlChars];
  221. if (r.location != NSNotFound)
  222. return nil;
  223. // Replace ' with '' since it is used as a string delimeter in the command
  224. // that we pass on to Vim to perform the search.
  225. [string replaceOccurrencesOfString:@"'"
  226. withString:@"''"
  227. options:NSLiteralSearch
  228. range:NSMakeRange(0, [string length])];
  229. // Replace \ with \\ to avoid Vim interpreting it as the beginning of a
  230. // character class.
  231. [string replaceOccurrencesOfString:@"\\"
  232. withString:@"\\\\"
  233. options:NSLiteralSearch
  234. range:NSMakeRange(0, [string length])];
  235. return string;
  236. }
  237. @end // NSString (MMExtras)
  238. @implementation NSColor (MMExtras)
  239. + (NSColor *)colorWithRgbInt:(unsigned)rgb
  240. {
  241. float r = ((rgb>>16) & 0xff)/255.0f;
  242. float g = ((rgb>>8) & 0xff)/255.0f;
  243. float b = (rgb & 0xff)/255.0f;
  244. return [NSColor colorWithDeviceRed:r green:g blue:b alpha:1.0f];
  245. }
  246. + (NSColor *)colorWithArgbInt:(unsigned)argb
  247. {
  248. float a = ((argb>>24) & 0xff)/255.0f;
  249. float r = ((argb>>16) & 0xff)/255.0f;
  250. float g = ((argb>>8) & 0xff)/255.0f;
  251. float b = (argb & 0xff)/255.0f;
  252. return [NSColor colorWithDeviceRed:r green:g blue:b alpha:a];
  253. }
  254. @end // NSColor (MMExtras)
  255. @implementation NSDictionary (MMExtras)
  256. + (id)dictionaryWithData:(NSData *)data
  257. {
  258. id plist = [NSPropertyListSerialization
  259. propertyListFromData:data
  260. mutabilityOption:NSPropertyListImmutable
  261. format:NULL
  262. errorDescription:NULL];
  263. return [plist isKindOfClass:[NSDictionary class]] ? plist : nil;
  264. }
  265. - (NSData *)dictionaryAsData
  266. {
  267. return [NSPropertyListSerialization dataFromPropertyList:self
  268. format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL];
  269. }
  270. @end
  271. @implementation NSMutableDictionary (MMExtras)
  272. + (id)dictionaryWithData:(NSData *)data
  273. {
  274. id plist = [NSPropertyListSerialization
  275. propertyListFromData:data
  276. mutabilityOption:NSPropertyListMutableContainers
  277. format:NULL
  278. errorDescription:NULL];
  279. return [plist isKindOfClass:[NSMutableDictionary class]] ? plist : nil;
  280. }
  281. @end
  282. void
  283. ASLInit()
  284. {
  285. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  286. // Allow for changing the log level via user defaults. If no key is found
  287. // the default log level will be used (which for ASL is to log everything
  288. // up to ASL_LEVEL_NOTICE). This key is an integer which corresponds to
  289. // the ASL_LEVEL_* macros (0 is most severe, 7 is debug level).
  290. id logLevelObj = [ud objectForKey:MMLogLevelKey];
  291. if (logLevelObj) {
  292. int logLevel = [logLevelObj intValue];
  293. if (logLevel < 0) logLevel = 0;
  294. if (logLevel > ASL_LEVEL_DEBUG) logLevel = ASL_LEVEL_DEBUG;
  295. ASLogLevel = logLevel;
  296. asl_set_filter(NULL, ASL_FILTER_MASK_UPTO(logLevel));
  297. }
  298. // Allow for changing whether a copy of each log should be sent to stderr
  299. // (this defaults to NO if this key is missing in the user defaults
  300. // database). The above filter mask is applied to logs going to stderr,
  301. // contrary to how "vanilla" ASL works.
  302. BOOL logToStdErr = [ud boolForKey:MMLogToStdErrKey];
  303. if (logToStdErr)
  304. asl_add_log_file(NULL, 2); // The file descriptor for stderr is 2
  305. }