Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge from upstream

  • Loading branch information...
commit 604944bc3dc52f6f8aa28212a529d99679ced688 2 parents d619d30 + c143344
@andyarvanitis andyarvanitis authored
Showing with 1,863 additions and 249 deletions.
  1. +8 −38 À La Carte Projects/XCFixin_DisableAnimations/XCFixin_DisableAnimations.m
  2. +6 −0 À La Carte Projects/XCFixin_DisableAnimations/XCFixin_DisableAnimations.xcodeproj/project.pbxproj
  3. +8 −26 À La Carte Projects/XCFixin_DisableWriteStateData/XCFixin_DisableWriteStateData.m
  4. +6 −0 À La Carte Projects/XCFixin_DisableWriteStateData/XCFixin_DisableWriteStateData.xcodeproj/project.pbxproj
  5. +13 −65 À La Carte Projects/XCFixin_FindFix/XCFixin_FindFix.m
  6. +6 −0 À La Carte Projects/XCFixin_FindFix/XCFixin_FindFix.xcodeproj/project.pbxproj
  7. +22 −80 À La Carte Projects/XCFixin_HideDistractions/XCFixin_HideDistractions.m
  8. +6 −0 À La Carte Projects/XCFixin_HideDistractions/XCFixin_HideDistractions.xcodeproj/project.pbxproj
  9. +8 −29 À La Carte Projects/XCFixin_InhibitTabNextPlaceholder/XCFixin_InhibitTabNextPlaceholder.m
  10. +6 −0 ...arte Projects/XCFixin_InhibitTabNextPlaceholder/XCFixin_InhibitTabNextPlaceholder.xcodeproj/project.pbxproj
  11. +2 −0  À La Carte Projects/XCFixin_OptionClickDocumentation/English.lproj/InfoPlist.strings
  12. +34 −0 À La Carte Projects/XCFixin_OptionClickDocumentation/Info.plist
  13. +40 −0 À La Carte Projects/XCFixin_OptionClickDocumentation/XCFixin_OptionClickDocumentation.m
  14. +261 −0 ... Carte Projects/XCFixin_OptionClickDocumentation/XCFixin_OptionClickDocumentation.xcodeproj/project.pbxproj
  15. +7 −0 ...nClickDocumentation/XCFixin_OptionClickDocumentation.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  16. +1 −0  À La Carte Projects/XCFixin_UserScripts/.gitignore
  17. +2 −0  À La Carte Projects/XCFixin_UserScripts/English.lproj/InfoPlist.strings
  18. +32 −0 À La Carte Projects/XCFixin_UserScripts/Info.plist
  19. +126 −0 À La Carte Projects/XCFixin_UserScripts/UserScripts.org
  20. +719 −0 À La Carte Projects/XCFixin_UserScripts/XCFixin_UserScripts.m
  21. +259 −0 À La Carte Projects/XCFixin_UserScripts/XCFixin_UserScripts.xcodeproj/project.pbxproj
  22. +7 −0 ...rte Projects/XCFixin_UserScripts/XCFixin_UserScripts.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  23. +107 −0 À La Carte Projects/XCFixin_UserScripts/notes.org
  24. +27 −9 README.md
  25. +61 −0 Shared Code/XCFixin.h
  26. +63 −0 Shared Code/XCFixin.m
  27. +6 −0 XCFixins.xcworkspace/contents.xcworkspacedata
  28. +20 −2 XCFixins.xcworkspace/xcshareddata/xcschemes/All Fixins.xcscheme
View
46 À La Carte Projects/XCFixin_DisableAnimations/XCFixin_DisableAnimations.m
@@ -1,6 +1,8 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
+#import "XCFixin.h"
+
static IMP gOriginalInitWithDuration = nil;
static IMP gOriginalSetDuration = nil;
@@ -11,61 +13,29 @@ @implementation XCFixin_DisableAnimations
static void overrideInitWithDuration(id self, SEL _cmd, NSTimeInterval arg1, NSAnimationCurve arg2)
{
-
/* -[NSAnimation initWithDuration:(NSTimeInterval)duration animationCurve:(NSAnimationCurve)animationCurve] */
-
((void (*)(id, SEL, NSTimeInterval, NSAnimationCurve))gOriginalInitWithDuration)(self, _cmd, 0.0, arg2);
-
}
static void overrideSetDuration(id self, SEL _cmd, NSTimeInterval arg1)
{
-
/* -[NSAnimation setDuration:(NSTimeInterval)duration] */
-
((void (*)(id, SEL, NSTimeInterval))gOriginalSetDuration)(self, _cmd, 0.0);
-
}
+ (void)pluginDidLoad: (NSBundle *)plugin
{
-
- Class class = nil;
- Method originalMethod = nil;
-
- NSLog(@"%@ initializing...", NSStringFromClass([self class]));
+ XCFixinPreflight();
/* Override -[NSAnimation initWithDuration:(NSTimeInterval)duration animationCurve:(NSAnimationCurve)animationCurve] */
-
- if (!(class = NSClassFromString(@"NSAnimation")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(initWithDuration: animationCurve:))))
- goto failed;
-
- if (!(gOriginalInitWithDuration = method_setImplementation(originalMethod, (IMP)&overrideInitWithDuration)))
- goto failed;
+ gOriginalInitWithDuration = XCFixinOverrideMethodString(@"NSAnimation", @selector(initWithDuration: animationCurve:), (IMP)&overrideInitWithDuration);
+ XCFixinAssertOrPerform(gOriginalInitWithDuration, goto failed);
/* Override -[NSAnimation setDuration:(NSTimeInterval)duration] */
+ gOriginalSetDuration = XCFixinOverrideMethodString(@"NSAnimation", @selector(setDuration:), (IMP)&overrideSetDuration);
+ XCFixinAssertOrPerform(gOriginalSetDuration, goto failed);
- if (!(class = NSClassFromString(@"NSAnimation")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(setDuration:))))
- goto failed;
-
- if (!(gOriginalSetDuration = method_setImplementation(originalMethod, (IMP)&overrideSetDuration)))
- goto failed;
-
- NSLog(@"%@ complete!", NSStringFromClass([self class]));
- return;
- failed:
- {
-
- NSLog(@"%@ failed. :(", NSStringFromClass([self class]));
-
- }
-
+ XCFixinPostflight();
}
@end
View
6 À La Carte Projects/XCFixin_DisableAnimations/XCFixin_DisableAnimations.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 5514A3FA1506CB8F00A8AD77 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5514A3F91506CB8F00A8AD77 /* XCFixin.m */; };
55C015D212B7BC2500354E5C /* XCFixin_DisableAnimations.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_DisableAnimations.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -15,6 +16,8 @@
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5514A3F91506CB8F00A8AD77 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEEB150067CB00A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
55C015D112B7BC2500354E5C /* XCFixin_DisableAnimations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_DisableAnimations.m; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* XCFixin_DisableAnimations.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_DisableAnimations.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -63,6 +66,8 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
+ 5595EEEB150067CB00A30634 /* XCFixin.h */,
+ 5514A3F91506CB8F00A8AD77 /* XCFixin.m */,
55C015D112B7BC2500354E5C /* XCFixin_DisableAnimations.m */,
);
name = Classes;
@@ -149,6 +154,7 @@
buildActionMask = 2147483647;
files = (
55C015D212B7BC2500354E5C /* XCFixin_DisableAnimations.m in Sources */,
+ 5514A3FA1506CB8F00A8AD77 /* XCFixin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
34 À La Carte Projects/XCFixin_DisableWriteStateData/XCFixin_DisableWriteStateData.m
@@ -1,6 +1,8 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
+#import "XCFixin.h"
+
static IMP gOriginalWriteStateData = nil;
@interface XCFixin_DisableWriteStateData : NSObject
@@ -10,39 +12,19 @@ @implementation XCFixin_DisableWriteStateData
static BOOL overrideWriteStateData(id self, SEL _cmd)
{
-
+ /* -(BOOL)[IDEWorkspaceDocument writeStateData] */
return YES;
-
}
+ (void)pluginDidLoad: (NSBundle *)plugin
{
-
- Class class = nil;
- Method originalMethod = nil;
-
- NSLog(@"%@ initializing...", NSStringFromClass([self class]));
-
- /* Override -(BOOL)[IDEWorkspaceDocument writeStateData]; */
+ XCFixinPreflight();
- if (!(class = NSClassFromString(@"IDEWorkspaceDocument")))
- goto failed;
+ /* Override -(BOOL)[IDEWorkspaceDocument writeStateData] */
+ gOriginalWriteStateData = XCFixinOverrideMethodString(@"IDEWorkspaceDocument", @selector(writeStateData), (IMP)&overrideWriteStateData);
+ XCFixinAssertOrPerform(gOriginalWriteStateData, goto failed);
- if (!(originalMethod = class_getInstanceMethod(class, @selector(writeStateData))))
- goto failed;
-
- if (!(gOriginalWriteStateData = method_setImplementation(originalMethod, (IMP)&overrideWriteStateData)))
- goto failed;
-
- NSLog(@"%@ complete!", NSStringFromClass([self class]));
- return;
- failed:
- {
-
- NSLog(@"%@ failed. :(", NSStringFromClass([self class]));
-
- }
-
+ XCFixinPostflight();
}
@end
View
6 À La Carte Projects/XCFixin_DisableWriteStateData/XCFixin_DisableWriteStateData.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 5514A3FD1506CB9500A8AD77 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5514A3FC1506CB9500A8AD77 /* XCFixin.m */; };
55C015D212B7BC2500354E5C /* XCFixin_DisableWriteStateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_DisableWriteStateData.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -15,6 +16,8 @@
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5514A3FC1506CB9500A8AD77 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEED150067CE00A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
55C015D112B7BC2500354E5C /* XCFixin_DisableWriteStateData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_DisableWriteStateData.m; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* XCFixin_DisableWriteStateData.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_DisableWriteStateData.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -63,6 +66,8 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
+ 5595EEED150067CE00A30634 /* XCFixin.h */,
+ 5514A3FC1506CB9500A8AD77 /* XCFixin.m */,
55C015D112B7BC2500354E5C /* XCFixin_DisableWriteStateData.m */,
);
name = Classes;
@@ -149,6 +154,7 @@
buildActionMask = 2147483647;
files = (
55C015D212B7BC2500354E5C /* XCFixin_DisableWriteStateData.m in Sources */,
+ 5514A3FD1506CB9500A8AD77 /* XCFixin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
78 À La Carte Projects/XCFixin_FindFix/XCFixin_FindFix.m
@@ -1,6 +1,8 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
+#import "XCFixin.h"
+
static IMP gOriginalInsertScopeBar = nil;
static IMP gOriginalAdjustViewsForHeightOffset = nil;
static IMP gOriginalSetFinderMode = nil;
@@ -13,119 +15,65 @@ @implementation XCFixin_FindFix
static void overrideInsertScopeBar(id self, SEL _cmd, id arg1, unsigned long long arg2, BOOL arg3)
{
-
/* -(void)[DVTScopeBarsManager insertScopeBar:(id)arg1 atIndex:(unsigned long long)arg2 animate:(BOOL)arg3] */
-
((void (*)(id, SEL, id, unsigned long long, BOOL))gOriginalInsertScopeBar)(self, _cmd, arg1, arg2, NO);
-
}
static void overrideAdjustViewsForHeightOffset(id self, SEL _cmd, double arg1, BOOL arg2, id arg3)
{
-
/* -(void)[DVTScopeBarsManager _adjustViewsForHeightOffset:(double)arg1 animate:(BOOL)arg2 extraAnimations:(id)arg3] */
-
- ((void (*)(id, SEL, double, BOOL, id))gOriginalAdjustViewsForHeightOffset)(self, _cmd, arg1, NO, nil);
-
+ ((void (*)(id, SEL, double, BOOL, id))gOriginalAdjustViewsForHeightOffset)(self, _cmd, arg1, arg2, arg3);
}
static void overrideSetFinderMode(id self, SEL _cmd, unsigned long long arg1)
{
-
/* -(void)[DVTFindBar setFinderMode:(unsigned long long)arg1] */
if (!arg1 && [[self valueForKey: @"supportsReplace"] boolValue])
arg1 = 1;
((void (*)(id, SEL, unsigned long long))gOriginalSetFinderMode)(self, _cmd, arg1);
-
}
static void overrideViewDidInstall(id self, SEL _cmd)
{
-
/* -(void)[DVTFindBar viewDidInstall] */
if ([[self valueForKey: @"supportsReplace"] boolValue])
{
-
[self setValue: [NSNumber numberWithUnsignedLongLong: 1] forKey: @"finderMode"];
[self setValue: [NSNumber numberWithDouble: 45.0] forKey: @"preferredViewHeight"];
-
}
((void (*)(id, SEL))gOriginalViewDidInstall)(self, _cmd);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.0), dispatch_get_main_queue(),
^{
-
[self setValue: [NSNumber numberWithBool: YES] forKey: @"showsOptions"];
-
});
-
}
+ (void)pluginDidLoad: (NSBundle *)plugin
{
-
- Class class = nil;
- Method originalMethod = nil;
-
- NSLog(@"%@ initializing...", NSStringFromClass([self class]));
+ XCFixinPreflight();
/* Override -(void)[DVTScopeBarsManager insertScopeBar:(id)arg1 atIndex:(unsigned long long)arg2 animate:(BOOL)arg3] */
-
- if (!(class = NSClassFromString(@"DVTScopeBarsManager")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(insertScopeBar: atIndex: animate:))))
- goto failed;
-
- if (!(gOriginalInsertScopeBar = method_setImplementation(originalMethod, (IMP)&overrideInsertScopeBar)))
- goto failed;
+ gOriginalInsertScopeBar = XCFixinOverrideMethodString(@"DVTScopeBarsManager", @selector(insertScopeBar: atIndex: animate:), (IMP)&overrideInsertScopeBar);
+ XCFixinAssertOrPerform(gOriginalInsertScopeBar, goto failed);
/* Override -(void)[DVTScopeBarsManager _adjustViewsForHeightOffset:(double)arg1 animate:(BOOL)arg2 extraAnimations:(id)arg3] */
-
- if (!(class = NSClassFromString(@"DVTScopeBarsManager")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(_adjustViewsForHeightOffset: animate: extraAnimations:))))
- goto failed;
-
- if (!(gOriginalAdjustViewsForHeightOffset = method_setImplementation(originalMethod, (IMP)&overrideAdjustViewsForHeightOffset)))
- goto failed;
+ gOriginalAdjustViewsForHeightOffset = XCFixinOverrideMethodString(@"DVTScopeBarsManager", @selector(_adjustViewsForHeightOffset: animate: extraAnimations:), (IMP)&overrideAdjustViewsForHeightOffset);
+ XCFixinAssertOrPerform(gOriginalAdjustViewsForHeightOffset, goto failed);
/* Override -(void)[DVTFindBar setFinderMode:(unsigned long long)arg1] */
-
- if (!(class = NSClassFromString(@"DVTFindBar")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(setFinderMode:))))
- goto failed;
-
- if (!(gOriginalSetFinderMode = method_setImplementation(originalMethod, (IMP)&overrideSetFinderMode)))
- goto failed;
+ gOriginalSetFinderMode = XCFixinOverrideMethodString(@"DVTFindBar", @selector(setFinderMode:), (IMP)&overrideSetFinderMode);
+ XCFixinAssertOrPerform(gOriginalSetFinderMode, goto failed);
/* Override -(void)[DVTFindBar viewDidInstall] */
+ gOriginalViewDidInstall = XCFixinOverrideMethodString(@"DVTFindBar", @selector(viewDidInstall), (IMP)&overrideViewDidInstall);
+ XCFixinAssertOrPerform(gOriginalViewDidInstall, goto failed);
- if (!(class = NSClassFromString(@"DVTFindBar")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(viewDidInstall))))
- goto failed;
-
- if (!(gOriginalViewDidInstall = method_setImplementation(originalMethod, (IMP)&overrideViewDidInstall)))
- goto failed;
-
- NSLog(@"%@ complete!", NSStringFromClass([self class]));
- return;
- failed:
- {
-
- NSLog(@"%@ failed. :(", NSStringFromClass([self class]));
-
- }
-
+ XCFixinPostflight();
}
@end
View
6 À La Carte Projects/XCFixin_FindFix/XCFixin_FindFix.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 5514A4001506CB9800A8AD77 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5514A3FF1506CB9800A8AD77 /* XCFixin.m */; };
55C015D212B7BC2500354E5C /* XCFixin_FindFix.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_FindFix.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -15,6 +16,8 @@
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5514A3FF1506CB9800A8AD77 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEEF150067D100A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
55C015D112B7BC2500354E5C /* XCFixin_FindFix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_FindFix.m; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* XCFixin_FindFix.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_FindFix.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -63,6 +66,8 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
+ 5595EEEF150067D100A30634 /* XCFixin.h */,
+ 5514A3FF1506CB9800A8AD77 /* XCFixin.m */,
55C015D112B7BC2500354E5C /* XCFixin_FindFix.m */,
);
name = Classes;
@@ -149,6 +154,7 @@
buildActionMask = 2147483647;
files = (
55C015D212B7BC2500354E5C /* XCFixin_FindFix.m in Sources */,
+ 5514A4001506CB9800A8AD77 /* XCFixin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
102 À La Carte Projects/XCFixin_HideDistractions/XCFixin_HideDistractions.m
@@ -1,39 +1,7 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
-#define HDAssertMessageFormat @"Assertion failed (file: %s, function: %s, line: %u): %s\n"
-#define HDNoOp (void)0
-
-#define HDAssertOrPerform(condition, action) \
-({ \
- \
- bool __evaluated_condition = false; \
- \
- __evaluated_condition = (condition); \
- \
- if (!__evaluated_condition) \
- { \
- \
- NSLog(HDAssertMessageFormat, __FILE__, __PRETTY_FUNCTION__, __LINE__, (#condition)); \
- action; \
- \
- } \
- \
-})
-
-#define HDAssertOrRaise(condition) HDAssertOrPerform((condition), [NSException raise: NSGenericException format: @"A XCFixin_HideDistractions exception occurred"])
-
-#define HDConfirmOrPerform(condition, action) \
-({ \
- \
- if (!(condition)) \
- { \
- \
- action; \
- \
- } \
- \
-})
+#import "XCFixin.h"
static NSString *const kDisableAnimationsClassName = @"XCFixin_DisableAnimations";
@@ -42,65 +10,38 @@ @interface XCFixin_HideDistractions : NSObject
@implementation XCFixin_HideDistractions
-+ (void)pluginDidLoad: (NSBundle *)plugin
-{
-
- NSLog(@"%@ initializing...", NSStringFromClass([self class]));
-
- [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationFinishedLaunching:)
- name: NSApplicationDidFinishLaunchingNotification object: nil];
-
- NSLog(@"%@ complete!", NSStringFromClass([self class]));
- return;
- failed:
- {
-
- NSLog(@"%@ failed. :(", NSStringFromClass([self class]));
-
- }
-
-}
-
+ (void)applicationFinishedLaunching: (NSNotification *)notification
{
-
NSMenu *mainMenu = nil,
*viewMenu = nil;
NSMenuItem *viewMenuItem = nil,
*hideDistractionsMenuItem = nil;
mainMenu = [NSApp mainMenu];
-
- HDAssertOrPerform(mainMenu, return);
+ XCFixinAssertOrPerform(mainMenu, return);
viewMenuItem = [mainMenu itemWithTitle: @"View"];
-
- HDAssertOrPerform(viewMenuItem, return);
+ XCFixinAssertOrPerform(viewMenuItem, return);
viewMenu = [viewMenuItem submenu];
+ XCFixinAssertOrPerform(viewMenuItem, return);
- HDAssertOrPerform(viewMenuItem, return);
-
- hideDistractionsMenuItem = [viewMenu addItemWithTitle: @"Hide Distractions" action: @selector(hideDistractions:) keyEquivalent: @"d"];
-
- HDAssertOrPerform(hideDistractionsMenuItem, return);
-
+ /* The 'Hide Distractions' menu item key combination can be set below. */
+ hideDistractionsMenuItem = [[[NSMenuItem alloc] initWithTitle: @"Hide Distractions" action: @selector(hideDistractions:) keyEquivalent: @"D"] autorelease];
+ XCFixinAssertOrPerform(hideDistractionsMenuItem, return);
[hideDistractionsMenuItem setKeyEquivalentModifierMask: (NSCommandKeyMask | NSShiftKeyMask)];
[hideDistractionsMenuItem setTarget: self];
-
+ [viewMenu addItem: hideDistractionsMenuItem];
}
+ (void)clickMenuItem: (NSMenuItem *)menuItem
{
-
if (menuItem && [menuItem isEnabled])
[NSApp sendAction: [menuItem action] to: [menuItem target] from: menuItem];
-
}
+ (NSMenuItem *)menuItemWithPath: (NSString *)menuItemPath
{
-
NSArray *pathComponents = nil;
NSString *currentPathComponent = nil;
NSMenu *currentMenu = nil;
@@ -110,44 +51,36 @@ + (NSMenuItem *)menuItemWithPath: (NSString *)menuItemPath
NSParameterAssert([menuItemPath length]);
currentMenu = [NSApp mainMenu];
-
- HDAssertOrPerform(currentMenu, return nil);
+ XCFixinAssertOrPerform(currentMenu, return nil);
pathComponents = [menuItemPath componentsSeparatedByString: @" > "];
for (currentPathComponent in pathComponents)
{
-
- HDAssertOrRaise(currentPathComponent);
- HDAssertOrRaise([currentPathComponent length]);
+ XCFixinAssertOrRaise(currentPathComponent);
+ XCFixinAssertOrRaise([currentPathComponent length]);
[currentMenu update];
currentMenuItem = [currentMenu itemWithTitle: currentPathComponent];
-
- HDConfirmOrPerform(currentMenuItem && [currentMenuItem isEnabled], return nil);
+ XCFixinConfirmOrPerform(currentMenuItem && [currentMenuItem isEnabled], return nil);
if ([currentMenuItem hasSubmenu])
currentMenu = [currentMenuItem submenu];
-
else
currentMenu = nil;
-
}
return currentMenuItem;
-
}
+ (void)hideDistractions: (id)sender
{
-
NSWindow *activeWindow = nil;
/* Get the front window */
activeWindow = [NSApp keyWindow];
-
- HDConfirmOrPerform(activeWindow, return);
+ XCFixinConfirmOrPerform(activeWindow, return);
/* If we get here, everything checks out; that is, we have an active window and we have
references to the required menus items. */
@@ -174,7 +107,16 @@ + (void)hideDistractions: (id)sender
if (NSClassFromString(kDisableAnimationsClassName))
[activeWindow enableFlushWindow];
+}
++ (void)pluginDidLoad: (NSBundle *)plugin
+{
+ XCFixinPreflight();
+
+ [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationFinishedLaunching:)
+ name: NSApplicationDidFinishLaunchingNotification object: nil];
+
+ XCFixinPostflight();
}
@end
View
6 À La Carte Projects/XCFixin_HideDistractions/XCFixin_HideDistractions.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 5514A4031506CB9E00A8AD77 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5514A4021506CB9E00A8AD77 /* XCFixin.m */; };
55C015D212B7BC2500354E5C /* XCFixin_HideDistractions.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_HideDistractions.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -15,6 +16,8 @@
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5514A4021506CB9E00A8AD77 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEF1150067D400A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
55C015D112B7BC2500354E5C /* XCFixin_HideDistractions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_HideDistractions.m; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* XCFixin_HideDistractions.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_HideDistractions.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -63,6 +66,8 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
+ 5595EEF1150067D400A30634 /* XCFixin.h */,
+ 5514A4021506CB9E00A8AD77 /* XCFixin.m */,
55C015D112B7BC2500354E5C /* XCFixin_HideDistractions.m */,
);
name = Classes;
@@ -149,6 +154,7 @@
buildActionMask = 2147483647;
files = (
55C015D212B7BC2500354E5C /* XCFixin_HideDistractions.m in Sources */,
+ 5514A4031506CB9E00A8AD77 /* XCFixin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
37 À La Carte Projects/XCFixin_InhibitTabNextPlaceholder/XCFixin_InhibitTabNextPlaceholder.m
@@ -1,6 +1,8 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
+#import "XCFixin.h"
+
static IMP gOriginalMoveToNextPlaceholderFromCharacterIndex = nil;
@interface XCFixin_InhibitTabNextPlaceholder : NSObject
@@ -10,44 +12,21 @@ @implementation XCFixin_InhibitTabNextPlaceholder
static BOOL overrideMoveToNextPlaceholderFromCharacterIndex(id self, SEL _cmd, unsigned long long characterIndex, BOOL forward, BOOL onlyIfNearby)
{
-
/* -(BOOL)[DVTCompletingTextView _moveToNextPlaceholderFromCharacterIndex:(unsigned long long)arg1 forward:(BOOL)arg2 onlyIfNearby:(BOOL)arg3; */
-
- if (onlyIfNearby)
- return NO;
-
+ XCFixinConfirmOrPerform(!onlyIfNearby, return NO);
return ((BOOL (*)(id, SEL, unsigned long long, BOOL, BOOL))gOriginalMoveToNextPlaceholderFromCharacterIndex)(self, _cmd, characterIndex, forward, onlyIfNearby);
-
}
+ (void)pluginDidLoad: (NSBundle *)plugin
{
-
- Class class = nil;
- Method originalMethod = nil;
-
- NSLog(@"%@ initializing...", NSStringFromClass([self class]));
+ XCFixinPreflight();
/* Override -(BOOL)[DVTCompletingTextView _moveToNextPlaceholderFromCharacterIndex:(unsigned long long)arg1 forward:(BOOL)arg2 onlyIfNearby:(BOOL)arg3] */
+ gOriginalMoveToNextPlaceholderFromCharacterIndex = XCFixinOverrideMethodString(@"DVTCompletingTextView",
+ @selector(_moveToNextPlaceholderFromCharacterIndex: forward: onlyIfNearby:), (IMP)&overrideMoveToNextPlaceholderFromCharacterIndex);
+ XCFixinAssertOrPerform(gOriginalMoveToNextPlaceholderFromCharacterIndex, goto failed);
- if (!(class = NSClassFromString(@"DVTCompletingTextView")))
- goto failed;
-
- if (!(originalMethod = class_getInstanceMethod(class, @selector(_moveToNextPlaceholderFromCharacterIndex: forward: onlyIfNearby:))))
- goto failed;
-
- if (!(gOriginalMoveToNextPlaceholderFromCharacterIndex = method_setImplementation(originalMethod, (IMP)&overrideMoveToNextPlaceholderFromCharacterIndex)))
- goto failed;
-
- NSLog(@"%@ complete!", NSStringFromClass([self class]));
- return;
- failed:
- {
-
- NSLog(@"%@ failed. :(", NSStringFromClass([self class]));
-
- }
-
+ XCFixinPostflight();
}
@end
View
6 ...e Projects/XCFixin_InhibitTabNextPlaceholder/XCFixin_InhibitTabNextPlaceholder.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 5514A4061506CBA200A8AD77 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5514A4051506CBA200A8AD77 /* XCFixin.m */; };
55C015D212B7BC2500354E5C /* XCFixin_InhibitTabNextPlaceholder.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_InhibitTabNextPlaceholder.m */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
@@ -15,6 +16,8 @@
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5514A4051506CBA200A8AD77 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEF3150067D600A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
55C015D112B7BC2500354E5C /* XCFixin_InhibitTabNextPlaceholder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_InhibitTabNextPlaceholder.m; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* XCFixin_InhibitTabNextPlaceholder.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_InhibitTabNextPlaceholder.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -63,6 +66,8 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
+ 5595EEF3150067D600A30634 /* XCFixin.h */,
+ 5514A4051506CBA200A8AD77 /* XCFixin.m */,
55C015D112B7BC2500354E5C /* XCFixin_InhibitTabNextPlaceholder.m */,
);
name = Classes;
@@ -149,6 +154,7 @@
buildActionMask = 2147483647;
files = (
55C015D212B7BC2500354E5C /* XCFixin_InhibitTabNextPlaceholder.m in Sources */,
+ 5514A4061506CBA200A8AD77 /* XCFixin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
2  À La Carte Projects/XCFixin_OptionClickDocumentation/English.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
View
34 À La Carte Projects/XCFixin_OptionClickDocumentation/Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.themha.${PRODUCT_NAME:rfc1034Identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>NSPrincipalClass</key>
+ <string>XCFixin_OptionClickDocumentation</string>
+ <key>XC4Compatible</key>
+ <true/>
+ <key>XCGCReady</key>
+ <true/>
+ <key>XCPluginHasUI</key>
+ <false/>
+</dict>
+</plist>
View
40 À La Carte Projects/XCFixin_OptionClickDocumentation/XCFixin_OptionClickDocumentation.m
@@ -0,0 +1,40 @@
+#import <Cocoa/Cocoa.h>
+#import <objc/runtime.h>
+
+#import "XCFixin.h"
+
+static IMP gOriginalShowPanel = nil;
+static IMP gOriginalLoadWindow = nil;
+
+@interface XCFixin_OptionClickDocumentation : NSObject
+@end
+
+@implementation XCFixin_OptionClickDocumentation
+
+static void overrideShowPanel(id self, SEL _cmd)
+{
+ /* -(void)[IDEQuickHelpOneShotController showPanel] */
+ [self performSelector: @selector(showDocumentation:)];
+}
+
+static void overrideLoadWindow(id self, SEL _cmd)
+{
+ /* -(void)[IDEQuickHelpOneShotWindowController loadWindow] */
+}
+
++ (void)pluginDidLoad: (NSBundle *)plugin
+{
+ XCFixinPreflight();
+
+ /* Override -(void)[IDEQuickHelpOneShotController showPanel] */
+ gOriginalShowPanel = XCFixinOverrideMethodString(@"IDEQuickHelpOneShotController", @selector(showPanel), (IMP)&overrideShowPanel);
+ XCFixinAssertOrPerform(gOriginalShowPanel, goto failed);
+
+ /* Override -(void)[IDEQuickHelpOneShotWindowController loadWindow] */
+ gOriginalLoadWindow = XCFixinOverrideMethodString(@"IDEQuickHelpOneShotWindowController", @selector(loadWindow), (IMP)&overrideLoadWindow);
+ XCFixinAssertOrPerform(gOriginalLoadWindow, goto failed);
+
+ XCFixinPostflight();
+}
+
+@end
View
261 ...rte Projects/XCFixin_OptionClickDocumentation/XCFixin_OptionClickDocumentation.xcodeproj/project.pbxproj
@@ -0,0 +1,261 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 55C015D212B7BC2500354E5C /* XCFixin_OptionClickDocumentation.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_OptionClickDocumentation.m */; };
+ 55CD34F61501DFEB00E4E589 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 55CD34F51501DFEB00E4E589 /* XCFixin.m */; };
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 5595EEDB150067A100A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
+ 55C015D112B7BC2500354E5C /* XCFixin_OptionClickDocumentation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_OptionClickDocumentation.m; sourceTree = "<group>"; };
+ 55CD34F51501DFEB00E4E589 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 8D5B49B6048680CD000E48DA /* XCFixin_OptionClickDocumentation.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_OptionClickDocumentation.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D5B49B3048680CD000E48DA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 089C166AFE841209C02AAC07 /* XCFixin_OptionClickDocumentation */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AFFE84173DC02AAC07 /* Classes */,
+ 089C167CFE841241C02AAC07 /* Resources */,
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+ 19C28FB8FE9D52D311CA2CBB /* Products */,
+ );
+ name = XCFixin_OptionClickDocumentation;
+ sourceTree = "<group>";
+ };
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+ );
+ name = "Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 089C167CFE841241C02AAC07 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B7048680CD000E48DA /* Info.plist */,
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 08FB77AFFE84173DC02AAC07 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 5595EEDB150067A100A30634 /* XCFixin.h */,
+ 55CD34F51501DFEB00E4E589 /* XCFixin.m */,
+ 55C015D112B7BC2500354E5C /* XCFixin_OptionClickDocumentation.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB8FE9D52D311CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B6048680CD000E48DA /* XCFixin_OptionClickDocumentation.xcplugin */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D5B49AC048680CD000E48DA /* XCFixin_OptionClickDocumentation */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "XCFixin_OptionClickDocumentation" */;
+ buildPhases = (
+ 8D5B49AF048680CD000E48DA /* Resources */,
+ 8D5B49B1048680CD000E48DA /* Sources */,
+ 8D5B49B3048680CD000E48DA /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = XCFixin_OptionClickDocumentation;
+ productInstallPath = "$(HOME)/Library/Bundles";
+ productName = XCFixin_OptionClickDocumentation;
+ productReference = 8D5B49B6048680CD000E48DA /* XCFixin_OptionClickDocumentation.xcplugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 089C1669FE841209C02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0410;
+ };
+ buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "XCFixin_OptionClickDocumentation" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 089C166AFE841209C02AAC07 /* XCFixin_OptionClickDocumentation */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D5B49AC048680CD000E48DA /* XCFixin_OptionClickDocumentation */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D5B49AF048680CD000E48DA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D5B49B1048680CD000E48DA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55C015D212B7BC2500354E5C /* XCFixin_OptionClickDocumentation.m in Sources */,
+ 55CD34F61501DFEB00E4E589 /* XCFixin.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C167EFE841241C02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB913B08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEPLOYMENT_LOCATION = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ DSTROOT = "$(HOME)";
+ GCC_ENABLE_OBJC_GC = supported;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
+ LD_RUNPATH_SEARCH_PATHS = /Developer;
+ PRODUCT_NAME = XCFixin_OptionClickDocumentation;
+ STRIP_INSTALLED_PRODUCT = YES;
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = xcplugin;
+ };
+ name = Debug;
+ };
+ 1DEB913C08733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEPLOYMENT_LOCATION = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ DSTROOT = "$(HOME)";
+ GCC_ENABLE_OBJC_GC = supported;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
+ LD_RUNPATH_SEARCH_PATHS = /Developer;
+ PRODUCT_NAME = XCFixin_OptionClickDocumentation;
+ STRIP_INSTALLED_PRODUCT = YES;
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = xcplugin;
+ };
+ name = Release;
+ };
+ 1DEB913F08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ };
+ name = Debug;
+ };
+ 1DEB914008733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "XCFixin_OptionClickDocumentation" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913B08733D840010E9CD /* Debug */,
+ 1DEB913C08733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "XCFixin_OptionClickDocumentation" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913F08733D840010E9CD /* Debug */,
+ 1DEB914008733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
View
7 ...ickDocumentation/XCFixin_OptionClickDocumentation.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:XCFixin_OptionClickDocumentation.xcodeproj">
+ </FileRef>
+</Workspace>
View
1  À La Carte Projects/XCFixin_UserScripts/.gitignore
@@ -0,0 +1 @@
+UserScripts.html
View
2  À La Carte Projects/XCFixin_UserScripts/English.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
View
32 À La Carte Projects/XCFixin_UserScripts/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.themha.${PRODUCT_NAME:rfc1034Identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>XC4Compatible</key>
+ <true/>
+ <key>XCGCReady</key>
+ <true/>
+ <key>XCPluginHasUI</key>
+ <false/>
+</dict>
+</plist>
View
126 À La Carte Projects/XCFixin_UserScripts/UserScripts.org
@@ -0,0 +1,126 @@
+* NO WARRANTY
+
+Do I have to spell it out? Surely we're all programmers here!
+Nevertheless - no warranty, it has bugs, it will probably blow up in
+your face, add you might lose data when it does.
+
+Also, don't forget to uninstall it and try again, before sending Apple
+bug reports about the problems you're having with Xcode 4.x - I'm sure
+they have better things to do than waste their time with my bugs.
+
+* User Scripts Fixin
+
+The fixin adds a new =Scripts= menu to Xcode 4.x. It works a little
+bit like the Xcode 3.x one.
+
+* Adding scripts
+
+The Scripts fixin looks in =~/Library/Application
+Support/Developer/Shared/Xcode/scripts/= for executable files, or
+symlinks to them. Any it finds have their names added to the new
+=Scripts= menu.
+
+* Running scripts
+
+Select script from the menu, and the script runs. The current
+selection is passed to the script as its standard input.
+
+The script's standard output replaces the current selection. Any
+standard error output is ignored.
+
+* Setting selection from a script
+
+Print the string =%%%{PBXSelection}%%%= to set the selection point.
+
+If this string appears once, the cursor is positioned at that point.
+
+If the string appears more than once, the text between the first two
+occurrences is selected.
+
+* Refreshing scripts
+
+At the bottom of the Scripts menu, there's an option =Refresh=. This
+re-reads the contents of the scripts directory, re-reads the script
+options (see below), and rebuilds the menu. So if you change the
+script options, or add or remove scripts, just select the =Refresh=
+option.
+
+* Script options
+
+You can add script options (including key equivalents) to your scripts
+by adding a file called =scripts.xml= in your scripts folder. It is an
+XML-style properly list, and it goes a bit like this:
+
+#+BEGIN_EXAMPLE
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Test Script</key>
+ <dict>
+ <key>keyEquivalent</key>
+ <string>C-M-5</string>
+ </dict>
+ <key>Insert Separator</key>
+ <dict>
+ <key>keyEquivalent</key>
+ <string>C-M-/</string>
+ </dict>
+</dict>
+</plist>
+#+END_EXAMPLE
+
+The key for the top-level dict is the name of the script (as shown on
+the menu), and each value is another dict holding script-specific
+options. Each script-specific option has a key, the option name, and a
+string value.
+
+The current option names are:
+
+- =keyEquivalent= :: value is the key equivalent in emacs notation,
+ modifier keys first (=C= for Control, =M= for Option, =s= for
+ Command, =S= for Shift), separated by =-=, then the key name.
+
+ (For example, =C-M-5= is Ctrl-Option-5. =s-C= is Command-C. etc.)
+
+ (The key name is passed verbatim to =-[NSMenuItem
+ setKeyEquivalent]=; I don't know what the full set of valid keys
+ might be.)
+
+- =stdinMode= :: value is string dictating what is used as script's
+ stdin, with valid options being:
+ - =none= :: no data sent
+ - =selection= (default) :: selection is used; no data
+ sent if no selection
+ - =linetextOrSelection= :: selection is used, if any;
+ current line (excluding line ending chars) sent
+ if no selection
+ - =lineOrSelection= :: selection is used, if any;
+ current line (including line ending chars) sent
+ if no selection
+
+- =reselectMode= :: value is string indicating how the selection
+ should be reinstated after the script has run,
+ with valid options being:
+ - =none= :: nothing is selected.
+ - =all= :: all script output is selected.
+ - =marker= (default) :: selection is set according
+ to =%%%{PBXSelection}%%%= markers in output.
+
+* Misfeatures
+
+- If you work in a language that uses non-Latin letters, you might not
+ have to look very far to find key equivalents that the fixin won't
+ accept.
+
+- The key equivalent emacs notation 'thing' is lame and I need to find
+ some better way of doing it.
+
+- Error reporting is not great. If you run Console.app, you might find
+ that the fixin has printed something useful there.
+
+- If you run a script on text that includes the string
+ "%%%{PBXSelection}%%%", that string will disappear. (Presumably this
+ happened in Xcode3 too?)
+
+- No support for column select.
View
719 À La Carte Projects/XCFixin_UserScripts/XCFixin_UserScripts.m
@@ -0,0 +1,719 @@
+#import <Cocoa/Cocoa.h>
+#import <CoreFoundation/CoreFoundation.h>
+#import <Foundation/Foundation.h>
+#import <objc/objc-runtime.h>
+#import <objc/runtime.h>
+
+#include <sys/stat.h>
+
+#import "XCFixin.h"
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+static NSString *GetObjectDescription(id obj)
+{
+ if(!obj)
+ return @"nil";
+ else
+ return [NSString stringWithFormat:@"(%s *)%p: %@",class_getName([obj class]),obj,obj];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+static NSTextView *FindIDETextView(void)
+{
+ NSWindow *mainWindow=[[NSApplication sharedApplication] mainWindow];
+ if(!mainWindow)
+ {
+ NSLog(@"Can't find IDE text view - no main window.\n");
+ return nil;
+ }
+
+ Class DVTCompletingTextView=objc_getClass("DVTCompletingTextView");
+ if(!DVTCompletingTextView)
+ {
+ NSLog(@"Can't find IDE text view - DVTCompletingTextView class unavailable.\n");
+ return nil;
+ }
+
+ id textView=nil;
+
+ for(NSResponder *responder=[mainWindow firstResponder];responder;responder=[responder nextResponder])
+ {
+ if([responder isKindOfClass:DVTCompletingTextView])
+ {
+ textView=responder;
+ break;
+ }
+ }
+
+ if(!textView)
+ {
+ NSLog(@"Can't find IDE text view - no DVTCompletingTextView in the responder chain.\n");
+ return nil;
+ }
+
+ return textView;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+enum ScriptReselectMode
+{
+ SRM_NONE,
+ SRM_MARKER,
+ SRM_ALL,
+};
+typedef enum ScriptReselectMode ScriptReselectMode;
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+enum ScriptStdinMode
+{
+ SSM_NONE,
+ SSM_SELECTION,
+ SSM_LINETEXT_OR_SELECTION,
+ SSM_LINE_OR_SELECTION,
+};
+typedef enum ScriptStdinMode ScriptStdinMode;
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+@interface XCFixin_Script:NSObject
+{
+ NSString *fileName_;
+ ScriptStdinMode stdinMode_;
+ ScriptReselectMode reselectMode_;
+}
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@implementation XCFixin_Script
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(id)initWithFileName:(NSString *)fileName
+{
+ if((self=[super init]))
+ {
+ fileName_=[fileName retain];
+ stdinMode_=SSM_SELECTION;
+ reselectMode_=SRM_MARKER;
+ }
+
+ return self;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+-(void)setReselectMode:(ScriptReselectMode)reselectMode
+{
+ reselectMode_=reselectMode;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+-(void)setStdinMode:(ScriptStdinMode)stdinMode
+{
+ stdinMode_=stdinMode;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+static NSRange NSMakeRangeFromStartAndEnd(NSUInteger start,NSUInteger end)
+{
+ NSRange r;
+
+ r.location=start;
+ r.length=end-start;
+
+ return r;
+}
+
+-(void)run
+{
+ NSLog(@"%s: path=%@\n",__FUNCTION__,fileName_);
+
+ NSTextView *textView=FindIDETextView();
+ if(!textView)
+ {
+ NSLog(@"Not running scripts - can't find IDE text view.\n");
+ return;
+ }
+
+ NSTextStorage *textStorage=[textView textStorage];
+ if(!textStorage)
+ {
+ NSLog(@"Not running scripts - IDE text view has no text storage.\n");
+ return;
+ }
+
+ NSArray *inputRanges=[textView selectedRanges];
+ NSLog(@"%s: %u selected ranges:\n",__FUNCTION__,[inputRanges count]);
+ for(NSUInteger i=0;i<[inputRanges count];++i)
+ {
+ NSRange range=[[inputRanges objectAtIndex:i] rangeValue];
+ NSLog(@" %u. %@\n",i,NSStringFromRange(range));
+ }
+
+ NSLog(@"%s: select range: %@\n",__FUNCTION__,NSStringFromRange([textView selectedRange]));
+
+ NSString *inputStr=nil;
+ NSData *inputData=nil;
+ NSRange inputRange=[textView selectedRange];
+ {
+ NSString *textStorageString=[textStorage string];
+
+ switch(stdinMode_)
+ {
+ case SSM_LINETEXT_OR_SELECTION:
+ case SSM_LINE_OR_SELECTION:
+ if(inputRange.length==0)
+ {
+ NSUInteger startIndex,contentsEndIndex,endIndex;
+ [textStorageString getLineStart:&startIndex
+ end:&endIndex
+ contentsEnd:&contentsEndIndex
+ forRange:inputRange];
+
+ inputRange.location=startIndex;
+
+ if(stdinMode_==SSM_LINE_OR_SELECTION)
+ inputRange.length=endIndex-startIndex;
+ else
+ inputRange.length=contentsEndIndex-startIndex;
+ }
+
+ // fall through
+ case SSM_SELECTION:
+ inputStr=[textStorageString substringWithRange:inputRange];
+ inputData=[inputStr dataUsingEncoding:NSUTF8StringEncoding];
+
+ // fall through
+ default:
+ break;
+ }
+ }
+
+ NSTask *task=[[[NSTask alloc] init] autorelease];
+
+ [task setLaunchPath:fileName_];
+ NSLog(@"%s: [task launchPath] = %@\n",__FUNCTION__,[task launchPath]);
+
+ NSPipe *stdinPipe=[NSPipe pipe];
+ NSPipe *stdoutPipe=[NSPipe pipe];
+ NSPipe *stderrPipe=[NSPipe pipe];
+
+ [task setStandardOutput:stdoutPipe];
+ [task setStandardInput:stdinPipe];
+ [task setStandardError:stderrPipe];
+
+ int exitCode=0;
+ NSData *outputData=nil;
+
+ @try
+ {
+ NSLog(@"%s: launching task...\n",__FUNCTION__);
+ [task launch];
+ NSLog(@"%s: task launched.\n",__FUNCTION__);
+
+ if(inputData)
+ {
+ @try
+ {
+ NSLog(@"%s: writing %u bytes to task's stdin...\n",__FUNCTION__,[inputData length]);
+ [[stdinPipe fileHandleForWriting] writeData:inputData];
+ NSLog(@"%s: wrote to task's stdin.\n",__FUNCTION__);
+ }
+ @catch(NSException *e)
+ {
+ // Maybe the task finished really quickly and it doesn't care what's in its stdin.
+ NSLog(@"%s: ignoring error (%@) writing to task's stdin.\n",__FUNCTION__,e);
+ }
+ }
+
+ [[stdinPipe fileHandleForWriting] closeFile];
+
+ @try
+ {
+ NSLog(@"%s: reading from task's stdout...\n",__FUNCTION__);
+ outputData=[[stdoutPipe fileHandleForReading] readDataToEndOfFile];
+ NSLog(@"%s: read %u bytes from task's stdout.\n",__FUNCTION__,[outputData length]);
+ }
+ @catch(NSException *e)
+ {
+ NSLog(@"%s: error (%@) reading from task's stdout.\n",__FUNCTION__,e);
+ }
+
+ NSLog(@"%s: waiting for task exit...\n",__FUNCTION__);
+ [task waitUntilExit];
+ NSLog(@"%s: task exit.\n",__FUNCTION__);
+
+ exitCode=[task terminationStatus];
+ if(exitCode!=0)
+ NSLog(@"Script failed - exit code %d.\n",exitCode);
+ }
+ @catch(NSException *e)
+ {
+ if([[e name] isEqualToString:@"NSInvalidArgumentException"])
+ {
+ exitCode=-1;
+
+ NSLog(@"Script launch failed.\n");
+ }
+ else
+ @throw e;
+ }
+ @finally
+ {
+ }
+
+ if(exitCode!=0)
+ outputData=nil;
+
+ if(outputData)
+ {
+ NSString *selectionMarker=@"%%\x25{PBXSelection}%%%";
+
+ NSString *outputStr=[[[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding] autorelease];
+
+ NSRange a;//before 1st marker
+ NSRange b;//between 1st marker and 2nd marker (selection goes here)
+ NSRange c;//after 2nd marker
+
+ switch(reselectMode_)
+ {
+ case SRM_ALL:
+ {
+ a=NSMakeRange(0,0);
+ b=NSMakeRange(0,[outputStr length]);
+ c=NSMakeRange([outputStr length],0);
+ }
+ break;
+
+ case SRM_MARKER:
+ {
+ NSRange r1=[outputStr rangeOfString:selectionMarker
+ options:NSLiteralSearch
+ range:NSMakeRangeFromStartAndEnd(0,
+ [outputStr length])];
+
+ if(r1.location==NSNotFound)
+ {
+ // no selection anywhere
+ a=NSMakeRangeFromStartAndEnd(0,
+ [outputStr length]);
+ c=b=NSMakeRange([outputStr length],
+ 0);
+ }
+ else
+ {
+ a=NSMakeRangeFromStartAndEnd(0,
+ r1.location);
+
+ NSRange r2=[outputStr rangeOfString:selectionMarker
+ options:NSLiteralSearch
+ range:NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
+ [outputStr length])];
+
+ if(r2.location==NSNotFound)
+ {
+ b=NSMakeRange(r1.location+[selectionMarker length],
+ 0);
+ c=NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
+ [outputStr length]);
+ }
+ else
+ {
+ b=NSMakeRangeFromStartAndEnd(r1.location+[selectionMarker length],
+ r2.location);
+ c=NSMakeRangeFromStartAndEnd(r2.location+[selectionMarker length],
+ [outputStr length]);
+ }
+ }
+ }
+ break;
+
+ default:
+ case SRM_NONE:
+ {
+ a=NSMakeRange(0,[outputStr length]);
+ b=NSMakeRange([outputStr length],0);
+ c=NSMakeRange([outputStr length],0);
+ }
+ break;
+ }
+
+
+ outputStr=[[[outputStr substringWithRange:a] stringByAppendingString:[outputStr substringWithRange:b]] stringByAppendingString:[outputStr substringWithRange:c]];
+
+ [textView breakUndoCoalescing];
+
+ // don't insert text if the two strings are actually the same.
+ //
+ // this is a fix for scripts that just pop a %%%{PBXSeleciton}%%%
+ // into their input to put the cursor somewhere.
+ if(![outputStr isEqualToString:inputStr])
+ {
+ [textView insertText:outputStr
+ replacementRange:inputRange];
+ }
+
+ [textView setSelectedRange:NSMakeRange(inputRange.location+a.length,
+ b.length)];
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(void)dealloc
+{
+ NSLog(@"%s: (%s *)%p: %@\n",__FUNCTION__,class_getName([self class]),self,fileName_);
+
+ [fileName_ release];
+ fileName_=nil;
+
+ [super dealloc];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@interface XCFixin_ScriptsHandler:NSObject
+
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@implementation XCFixin_ScriptsHandler
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+static NSString *SystemFolderName(int folderType,int domain)
+{
+ OSErr err;
+
+ FSRef folder;
+ err=FSFindFolder(domain,folderType,kCreateFolder,&folder);
+ if(err!=noErr)
+ return nil;
+
+ CFURLRef url=CFURLCreateFromFSRef(kCFAllocatorDefault,&folder);
+ NSString *result=[(NSURL *)url path];
+ CFRelease(url);
+
+ return result;
+}
+
+-(void)refreshScriptsMenu
+{
+ NSMenu *mainMenu=[NSApp mainMenu];
+ if(!mainMenu)
+ {
+ NSLog(@"%s: main menu not found.\n",__FUNCTION__);
+ return;
+ }
+
+ int scriptsMenuIndex=[mainMenu indexOfItemWithTitle:@"Scripts"];
+ if(scriptsMenuIndex<0)
+ {
+ NSLog(@"%s: Scripts menu not found.\n",__FUNCTION__);
+ return;
+ }
+
+ NSMenu *scriptsMenu=[[mainMenu itemAtIndex:scriptsMenuIndex] submenu];
+
+ //
+ [scriptsMenu removeAllItems];
+
+ NSString *appSupportFolderName=SystemFolderName(kApplicationSupportFolderType,kUserDomain);
+ NSLog(@"appSupportFolderName=%@\n",appSupportFolderName);
+
+ NSString *scriptsFolderName=[NSString pathWithComponents:[NSArray arrayWithObjects:appSupportFolderName,@"Developer/Shared/Xcode/Scripts",nil]];
+ NSLog(@"scriptsFolderName=%@\n",scriptsFolderName);
+
+ NSString *scriptsPListName=[NSString pathWithComponents:[NSArray arrayWithObjects:scriptsFolderName,@"Scripts.xml",nil]];
+ NSLog(@"scriptsPListName=%@\n",scriptsPListName);
+ NSDictionary *scriptsProperties=[NSDictionary dictionaryWithContentsOfFile:scriptsPListName];
+ if(!scriptsProperties)
+ NSLog(@"%s: No scripts plist loaded.\n",__FUNCTION__);
+ else
+ NSLog(@"%s: Scripts plist: %@\n",__FUNCTION__,scriptsProperties);
+
+ NSArray *scriptsFolderContents=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:scriptsFolderName
+ error:nil];
+ if([scriptsFolderContents count]>0)
+ {
+ NSMutableArray *scripts=[NSMutableArray arrayWithCapacity:0];
+
+ NSFileManager *defaultManager=[NSFileManager defaultManager];
+
+ for(NSUInteger i=0;i<[scriptsFolderContents count];++i)
+ {
+ NSString *name=[scriptsFolderContents objectAtIndex:i];
+ NSString *path=[NSString pathWithComponents:[NSArray arrayWithObjects:scriptsFolderName,name,nil]];
+
+ struct stat st;
+ if(stat([path UTF8String],&st)!=0)
+ {
+ NSLog(@"%@: not a script (stat failed)\n",path);
+ continue;
+ }
+
+ if(!(st.st_mode&(S_IFLNK|S_IFREG)))
+ {
+ NSLog(@"%@: not a script (not symlink or regular file)\n",path);
+ continue;
+ }
+
+ if(![defaultManager isExecutableFileAtPath:path])
+ {
+ NSLog(@"%@: not a script (not executable)\n",path);
+ continue;
+ }
+
+ [scripts addObject:name];
+ }
+
+ if([scripts count]>0)
+ {
+ for(NSUInteger scriptIdx=0;scriptIdx<[scripts count];++scriptIdx)
+ {
+ NSString *name=[scripts objectAtIndex:scriptIdx];
+ NSString *path=[NSString pathWithComponents:[NSArray arrayWithObjects:scriptsFolderName,name,nil]];
+
+ NSLog(@"Creating XCFixin_Script for %@.\n",path);
+ XCFixin_Script *script=[[[XCFixin_Script alloc] initWithFileName:path] autorelease];
+
+ NSMenuItem *scriptMenuItem=[[[NSMenuItem alloc] initWithTitle:name
+ action:nil
+ keyEquivalent:@""] autorelease];
+ [scriptMenuItem setTarget:self];
+ [scriptMenuItem setAction:@selector(runScriptAction:)];
+ [scriptMenuItem setRepresentedObject:script];
+
+ NSDictionary *scriptProperties=[scriptsProperties objectForKey:name];
+ if(![scriptProperties isKindOfClass:[NSDictionary class]])
+ scriptProperties=nil;
+
+ NSLog(@" Script properties: %@\n",scriptProperties);
+
+ NSString *keyEquivalent=[scriptProperties objectForKey:@"keyEquivalent"];
+ if(keyEquivalent&&[keyEquivalent length]>0)
+ {
+ // Yeah, OK, so I just completely could NOT work out how you're supposed to
+ // do this officially. So you have to use emacs notation.
+ //
+ // C- = control
+ // M- = Alt/Option ("Meta")
+ // S- = Shift
+ // s- = Command ("super")
+
+ unsigned modifiers=0;
+
+ for(NSUInteger i=0;i+1<[keyEquivalent length];i+=2)
+ {
+ char c=[keyEquivalent characterAtIndex:i];
+
+ switch(c)
+ {
+ case 'C':
+ modifiers|=NSControlKeyMask;
+ break;
+
+ case 'M':
+ modifiers|=NSAlternateKeyMask;
+ break;
+
+ case 'S':
+ modifiers|=NSShiftKeyMask;
+ break;
+
+ case 's':
+ modifiers|=NSCommandKeyMask;
+ break;
+
+ default:
+ // some kind of error here, or something??
+ //
+ // not like it's hard to spot or complicated to fix...
+ break;
+ }
+ }
+
+ [scriptMenuItem setKeyEquivalent:[keyEquivalent substringFromIndex:[keyEquivalent length]-1]];
+ [scriptMenuItem setKeyEquivalentModifierMask:modifiers];
+ }
+
+ NSString *stdinMode=[scriptProperties objectForKey:@"stdinMode"];
+ if(stdinMode)
+ {
+ if([stdinMode caseInsensitiveCompare:@"none"]==NSOrderedSame)
+ [script setStdinMode:SSM_NONE];
+ else if([stdinMode caseInsensitiveCompare:@"selection"]==NSOrderedSame)
+ [script setStdinMode:SSM_SELECTION];
+ else if([stdinMode caseInsensitiveCompare:@"lineorselection"]==NSOrderedSame)
+ [script setStdinMode:SSM_LINE_OR_SELECTION];
+ else if([stdinMode caseInsensitiveCompare:@"linetextorselection"]==NSOrderedSame)
+ [script setStdinMode:SSM_LINETEXT_OR_SELECTION];
+ }
+
+ NSString *reselectMode=[scriptProperties objectForKey:@"reselectMode"];
+ if(reselectMode)
+ {
+ if([reselectMode caseInsensitiveCompare:@"none"]==NSOrderedSame)
+ [script setReselectMode:SRM_NONE];
+ else if([reselectMode caseInsensitiveCompare:@"marker"]==NSOrderedSame)
+ [script setReselectMode:SRM_MARKER];
+ else if([reselectMode caseInsensitiveCompare:@"all"]==NSOrderedSame)
+ [script setReselectMode:SRM_ALL];
+ }
+
+ [scriptsMenu addItem:scriptMenuItem];
+ }
+ }
+
+ if([scriptsMenu numberOfItems]>0)
+ [scriptsMenu addItem:[NSMenuItem separatorItem]];
+ }
+
+ [[scriptsMenu addItemWithTitle:@"Refresh"
+ action:@selector(refreshScriptsMenuAction:)
+ keyEquivalent:@""] setTarget:self];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(IBAction)runScriptAction:(id)arg
+{
+ [[arg representedObject] run];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(IBAction)refreshScriptsMenuAction:(id)arg
+{
+ [self refreshScriptsMenu];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(BOOL)install
+{
+ NSMenu *mainMenu=[NSApp mainMenu];
+ if(!mainMenu)
+ {
+ NSLog(@"%s: main menu not found!\n",__FUNCTION__);
+ return NO;
+ }
+
+ NSInteger helpIndex=[mainMenu indexOfItemWithTitle:@"Help"];
+ if(helpIndex<0)
+ helpIndex=[mainMenu numberOfItems];
+
+ NSMenuItem *scriptsMenuItem=[mainMenu insertItemWithTitle:@"Scripts"
+ action:NULL
+ keyEquivalent:@""
+ atIndex:helpIndex];
+ [scriptsMenuItem setEnabled:YES];
+
+ NSMenu *scriptsMenu=[[[NSMenu alloc] initWithTitle:@"Scripts"] autorelease];
+ [scriptsMenu setAutoenablesItems:YES];
+
+ [scriptsMenuItem setSubmenu:scriptsMenu];
+
+ [self refreshScriptsMenu];
+
+ return YES;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+-(BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+ NSLog(@"%s: title=\"%@\"\n",__FUNCTION__,[menuItem title]);
+ return YES;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+static BOOL GetClasses(const char *name0,...)
+{
+ va_list v;
+ va_start(v,name0);
+
+ for(const char *name=name0;name;name=va_arg(v,const char *))
+ {
+ Class *c=va_arg(v,Class *);
+
+ *c=objc_getClass(name);
+ if(!*c)
+ {
+ NSLog(@"FATAL: class %s not found.\n",name);
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@interface XCFixin_UserScripts : NSObject
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@implementation XCFixin_UserScripts
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
++ (void)pluginDidLoad: (NSBundle *)plugin
+{
+ XCFixinPreflight();
+
+ XCFixin_ScriptsHandler *handler=[[XCFixin_ScriptsHandler alloc] init];
+ if(!handler)
+ NSLog(@"%s: handler init failed.\n",__FUNCTION__);
+ else
+ {
+ BOOL goodInstall=[handler install];
+ NSLog(@"%s: handler installed: %s\n",__FUNCTION__,goodInstall?"YES":"NO");
+ }
+
+ XCFixinPostflight();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+@end
View
259 À La Carte Projects/XCFixin_UserScripts/XCFixin_UserScripts.xcodeproj/project.pbxproj
@@ -0,0 +1,259 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 10E01A761506B97500BFF431 /* XCFixin.m in Sources */ = {isa = PBXBuildFile; fileRef = 10E01A751506B97500BFF431 /* XCFixin.m */; };
+ 55C015D212B7BC2500354E5C /* XCFixin_UserScripts.m in Sources */ = {isa = PBXBuildFile; fileRef = 55C015D112B7BC2500354E5C /* XCFixin_UserScripts.m */; };
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 10E01A751506B97500BFF431 /* XCFixin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XCFixin.m; path = "../../Shared Code/XCFixin.m"; sourceTree = "<group>"; };
+ 5595EEEB150067CB00A30634 /* XCFixin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XCFixin.h; path = "../../Shared Code/XCFixin.h"; sourceTree = "<group>"; };
+ 55C015D112B7BC2500354E5C /* XCFixin_UserScripts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCFixin_UserScripts.m; sourceTree = "<group>"; };
+ 8D5B49B6048680CD000E48DA /* XCFixin_UserScripts.xcplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCFixin_UserScripts.xcplugin; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D5B49B3048680CD000E48DA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 089C166AFE841209C02AAC07 /* XCFixin_UserScripts */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AFFE84173DC02AAC07 /* Classes */,
+ 089C167CFE841241C02AAC07 /* Resources */,
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+ 19C28FB8FE9D52D311CA2CBB /* Products */,
+ );
+ name = XCFixin_UserScripts;
+ sourceTree = "<group>";
+ };
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+ );
+ name = "Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 089C167CFE841241C02AAC07 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B7048680CD000E48DA /* Info.plist */,
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 08FB77AFFE84173DC02AAC07 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 5595EEEB150067CB00A30634 /* XCFixin.h */,
+ 10E01A751506B97500BFF431 /* XCFixin.m */,
+ 55C015D112B7BC2500354E5C /* XCFixin_UserScripts.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB8FE9D52D311CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B6048680CD000E48DA /* XCFixin_UserScripts.xcplugin */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D5B49AC048680CD000E48DA /* XCFixin_UserScripts */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "XCFixin_UserScripts" */;
+ buildPhases = (
+ 8D5B49AF048680CD000E48DA /* Resources */,
+ 8D5B49B1048680CD000E48DA /* Sources */,
+ 8D5B49B3048680CD000E48DA /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = XCFixin_UserScripts;
+ productInstallPath = "$(HOME)/Library/Bundles";
+ productName = XCFixin_UserScripts;
+ productReference = 8D5B49B6048680CD000E48DA /* XCFixin_UserScripts.xcplugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 089C1669FE841209C02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0420;
+ };
+ buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "XCFixin_UserScripts" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 089C166AFE841209C02AAC07 /* XCFixin_UserScripts */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D5B49AC048680CD000E48DA /* XCFixin_UserScripts */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D5B49AF048680CD000E48DA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D5B49B1048680CD000E48DA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55C015D212B7BC2500354E5C /* XCFixin_UserScripts.m in Sources */,
+ 10E01A761506B97500BFF431 /* XCFixin.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C167EFE841241C02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB913B08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEPLOYMENT_LOCATION = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ DSTROOT = "$(HOME)";
+ GCC_ENABLE_OBJC_GC = supported;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
+ LD_RUNPATH_SEARCH_PATHS = /Developer;
+ PRODUCT_NAME = XCFixin_UserScripts;
+ STRIP_INSTALLED_PRODUCT = YES;
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = xcplugin;
+ };
+ name = Debug;
+ };
+ 1DEB913C08733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEPLOYMENT_LOCATION = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
+ DSTROOT = "$(HOME)";
+ GCC_ENABLE_OBJC_GC = supported;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "/Library/Application Support/Developer/Shared/Xcode/Plug-ins";
+ LD_RUNPATH_SEARCH_PATHS = /Developer;
+ PRODUCT_NAME = XCFixin_UserScripts;
+ STRIP_INSTALLED_PRODUCT = YES;
+ VALID_ARCHS = "i386 x86_64";
+ WRAPPER_EXTENSION = xcplugin;
+ };
+ name = Release;
+ };
+ 1DEB913F08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ };
+ name = Debug;
+ };
+ 1DEB914008733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "XCFixin_UserScripts" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913B08733D840010E9CD /* Debug */,
+ 1DEB913C08733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "XCFixin_UserScripts" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913F08733D840010E9CD /* Debug */,
+ 1DEB914008733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
View
7 ... Projects/XCFixin_UserScripts/XCFixin_UserScripts.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:XCFixin_UserScripts.xcodeproj">
+ </FileRef>
+</Workspace>
View
107 À La Carte Projects/XCFixin_UserScripts/notes.org
@@ -0,0 +1,107 @@
+#+SEQ_TODO:TODO | DONE NOTDOING
+
+* TODO stdin mode `charOrSelection'
+
+Next character, or selection...
+
+(Useful for toupper and tolower macros, say.)
+
+* TODO column selection support
+
+Should be possible to figure out something reasonable if number of
+output lines exceeds number of input lines...
+
+* DONE reinstate selection
+ CLOSED: [2012-04-08 Sun 01:26]
+
+(Optionally) reselect entire script output. Sensible defaults might
+save on PBXSelection junk.
+
+e.g., for my toupper script...
+
+* DONE multiple tabs viewing same doc
+ CLOSED: [2012-04-01 Sun 01:01]
+
+Need to figure out which documentEditor has the focus...
+
+* DONE multiple windows viewing same doc
+ CLOSED: [2012-04-01 Sun 01:01]
+
+Is this any different from the tabs case?
+
+* DONE plist with key equivalents, etc.
+ CLOSED: [2012-03-31 Sat 18:25]
+
+* TODO Xcode3-style PBXFilePath (etc.)
+
+Seems like a very flaky approach. Would need to create copy of script
+with expansions in it. Would prevent use of binaries. Environment
+variables would be much safer and hardly less easy to use...
+
+* DONE Xcode3-style PBXSelection
+ CLOSED: [2012-04-02 Mon 01:37]
+
+* TODO inject junk into env?
+
+* DONE check script symlinks work
+ CLOSED: [2012-03-31 Sat 18:22]
+
+* NOTDOING replace -[NSTextView insertText:replacementRange:] with some NSTextStorage thingy or other
+ CLOSED: [2012-04-08 Sun 01:47]
+
+[resolved: looks like a bad idea, as the NSTextStorage methods don't
+seem to affect the undo queue!]
+
+Will this still work with the autocomplete stuff?
+
+Perhaps make it optional (some macros might still want to prompt an
+autocomplete popup).
+
+-[NSTextView insertText:replacementRange:] docs:
+
+"This method is the entry point for inserting text typed by the user
+and is generally not suitable for other purposes. Programmatic
+modification of the text is best done by operating on the text storage
+directly. Because this method pertains to the actions of the user, the
+text view must be editable for the insertion to work."
+
+* TODO scripts.xml name matching should be case-insensitive
+
+...to match the filing system behaviour.
+
+* DONE what if you have %%%{PBXSelection}%%% in the text?
+ CLOSED: [2012-04-08 Sun 01:47]
+
+[resolved: you live with it, or change the reselect mode]
+
+well, currently it disappears if you run a macro on it...
+
+What did Xcode3 do?
+
+* links
+
+[[http://www.culater.net/wiki/moin.cgi/CocoaReverseEngineering]]
+
+* class-dump notes
+
+** text file editor hierarchy
+
+@interface PBXSourceFileEditor : PBXTextFileEditor
+
+@interface PBXTextFileEditor : PBXFileEditor <NSTextViewDelegate, PBXIncrementalFindable, PBXEditorSelectedSymbol, PBXTrackableTaskObserver>
+
+@interface PBXFileEditor : PBXModule <NSTextViewDelegate>
+
+@interface PBXModule : NSWindowController <NSWindowDelegate, NSToolbarDelegate>
+
+PBXFileNavigator - FBXFileEditor *_fileEditor
+
+** -(NSTextView *)[PBXTextFileEditor textView]
+
+NSTextView<XCTextViewAdditions> *_textView;
+
+** stuff
+
+~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/
+
+IDEDefaultDebugArea
View
36 README.md
@@ -1,17 +1,35 @@
-__This branch is known to be compatible with Xcode 4.2.1. For Xcode 4.0.2 support, see the xcode_402 branch.__
+__This branch is known to be compatible with Xcode 4.3 and 4.3.2. For Xcode 4.0.2 support, see the xcode_402 branch.__
-To install all of the plugins, open XCFixins.xcworkspace and build it. To install a plugin individually, open its respective project and build it. In both cases, the plugins will be installed automatically as a part of the build process. Xcode must be relaunched for the plugins to take effect.
+__===== PROJECT DESCRIPTION =====__
-Plugins are installed into ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/.
+This project includes plugins that extend Xcode and fix some of its annoying behaviors, known as _fixins_.
-__XCFixin_DisableAnimations__: This plugin disables Xcode's various NSAnimation-based animations. For example, the Show/Hide Debug Area, Show/Hide Navigator, and Show/Hide Utilities animations are disabled with this plugin.
+__===== INSTALLATION =====__
-__XCFixin_DisableWriteStateData__: This plugin greatly improves Xcode's responsiveness by disabling the -[IDEWorkspaceDocument writeStateData] method. This method is of course undocumented and I'm unsure what data it typically writes. In my testing, I've noticed this plugin prevents the active source file from being remembered across Xcode launches, and it's very likely that it prevents other data from being written as well. I consider this plugin experimental and as such it is not installed automatically when building the XCFixins workspace; you must build this plugin individually to install it. With that said, on my machine this plugin *really* improves Xcode's responsiveness!
+To install all of the stable fixins, open XCFixins.xcworkspace and build it, and the fixins will automatically be installed as a part of the build process. Experimental fixins must be installed individually by building their respective projects found in the _À La Carte Projects_ directory.
-__XCFixin_FindFix__: By default, when Xcode's inline find bar opens, it doesn't display any options to customize searching. This plugin makes Xcode show all find options (such as "Ignore Case") in the find bar when it opens. This plugin also makes text-replacement the default mode in the inline find bar, giving immediate access to the "Replace" and "Replace All" buttons.
+Xcode must be relaunched for the fixins to take effect.
-__XCFixin_HideDistractions__: This plugin adds a new "Hide Distractions" menu item to the View menu, which hides auxiliary views in the active source-editing window. This plugin groups various operations into a single menu item, including: View > Hide Toolbar, View > Hide Debug Area, View > Navigators > Hide Navigator, View > Utilities > Hide Utilities, and View > Editor > Standard. Additionally, this menu item maximizes the active window to fill the available screen area. This plugin works best when the XCFixin_DisableAnimations plugin is also installed.
+Fixins are installed into ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/.
-__XCFixin_InhibitTabNextPlaceholder__: This plugin disables using the tab key to select between argument placeholders of a synthesized (by Xcode's code completion) method call. Xcode's default tab functionality can be annoying if you've synthesized a method invocation and attempt to indent something nearby before filling-in the argument placeholders; in such a case, Xcode jumps to the nearest argument placeholder instead of indenting. This plugin does not affect the "Jump to Next Placeholder" key binding in the Xcode preferences.
+__===== STABLE FIXINS =====__
-__XCFixin_CurrentLineHighlighter__: This plugin adds highlighting to the line of the current cursor position. This makes visually tracking the current insertion point easier. Many editors have this feature. When in the editor, the Editor menu item will have a new item, "Current Line Highlight Color...", which allows the user to select the color.
+__DisableAnimations__: This fixin disables Xcode's various NSAnimation-based animations. For example, the Show/Hide Debug Area, Show/Hide Navigator, and Show/Hide Utilities animations are disabled with this fixin.
+