Skip to content
Browse files

This is really just a skeleton for things to come.

There are two parts:
 1) Dialog plug-in for TextMate, this registers a “TextMate dialog server” connection to which it is possible to send a path to a nib file and optional arguments. This nib is then loaded in the TextMate program space, so it will appear with the proper window layer etc.
 2) tm_dialog is the shell tool to signal the Dialog plug-in

The idea is that TM commands can then just create a nib for their UI and use tm_dialog to have the nib shown, and get back the “result” from this nib, w/o having to do compile things etc. A suite of standard dialogs is planned which could replace the need for CocoaDialog.

There is currently one major problem with this approach: Distributed Objects seems to only allow one connection per task, so if you install this plug-in, you will lose ‘mate’ support, as that also works via Distributed Objects. Maybe there is a simple solution for this.
  • Loading branch information...
0 parents commit b06f34ce4caf8f9d0191a325ca062249699e63bd @sorbits sorbits committed Oct 21, 2006
78 Dialog PlugIn.tmproj
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>currentDocument</key>
+ <string>Dialog.mm</string>
+ <key>documents</key>
+ <array>
+ <dict>
+ <key>expanded</key>
+ <true/>
+ <key>name</key>
+ <string>Dialog PlugIn</string>
+ <key>regexFolderFilter</key>
+ <string>!.*/(\.[^/]*|CVS|include|3rd_party|\{arch\}|build|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$</string>
+ <key>sourceDirectory</key>
+ <string></string>
+ </dict>
+ </array>
+ <key>fileHierarchyDrawerWidth</key>
+ <integer>200</integer>
+ <key>metaData</key>
+ <dict>
+ <key>Dialog.h</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>0</integer>
+ <key>line</key>
+ <integer>5</integer>
+ </dict>
+ <key>firstVisibleColumn</key>
+ <integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>0</integer>
+ </dict>
+ <key>Dialog.mm</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>0</integer>
+ <key>line</key>
+ <integer>53</integer>
+ </dict>
+ <key>firstVisibleColumn</key>
+ <integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>35</integer>
+ </dict>
+ <key>tm_dialog.mm</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>0</integer>
+ <key>line</key>
+ <integer>3</integer>
+ </dict>
+ <key>firstVisibleColumn</key>
+ <integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <key>openDocuments</key>
+ <array>
+ <string>Dialog.mm</string>
+ <string>Dialog.h</string>
+ <string>tm_dialog.mm</string>
+ </array>
+ <key>showFileHierarchyDrawer</key>
+ <true/>
+ <key>windowFrame</key>
+ <string>{{515, 451}, {766, 578}}</string>
+</dict>
+</plist>
17 Dialog.h
@@ -0,0 +1,17 @@
+#import <Cocoa/Cocoa.h>
+
+@protocol TMPlugInController
+- (float)version;
+@end
+
+@protocol TextMateDialogServerProtocol
+- (int)textMateDialogServerProtocolVersion;
+- (void)showNib:(NSString*)aNib withArguments:(id)someArguments;
+@end
+
+@interface Dialog : NSObject
+{
+}
+- (id)initWithPlugInController:(id <TMPlugInController>)aController;
+- (void)dealloc;
+@end
87 Dialog.mm
@@ -0,0 +1,87 @@
+#import "Dialog.h"
+
+#ifndef enumerate
+#define enumerate(container,var) for(NSEnumerator* _enumerator = [container objectEnumerator]; var = [_enumerator nextObject]; )
+#endif
+
+@interface CatchAllNibLoader : NSObject
+{
+}
+@end
+
+@implementation CatchAllNibLoader
+- (void)setValue:(id)aValue forKey:(NSString*)aKey
+{
+ NSLog(@"%s %@ = %@", _cmd, aKey, aValue);
+}
+@end
+
+@interface DialogServer : NSObject <TextMateDialogServerProtocol>
+{
+}
+@end
+
+@implementation DialogServer
+- (int)textMateDialogServerProtocolVersion
+{
+ return 1;
+}
+
+- (void)showNib:(NSString*)aNibPath withArguments:(id)someArguments
+{
+ NSFileManager* fm = [NSFileManager defaultManager];
+
+ if(![aNibPath hasPrefix:@"/"]) // relative URL
+ aNibPath = [[fm currentDirectoryPath] stringByAppendingPathComponent:aNibPath];
+
+ if(![aNibPath hasSuffix:@".nib"])
+ aNibPath = [aNibPath stringByAppendingPathExtension:@"nib"];
+
+ if(![fm fileExistsAtPath:aNibPath])
+ {
+ NSLog(@"%s nib file not found: %@", _cmd, aNibPath);
+ return;
+ }
+
+ NSNib* nib = [[NSNib alloc] initWithContentsOfURL:[NSURL fileURLWithPath:aNibPath]];
+ if(!nib)
+ {
+ NSLog(@"%s failed loading nib: %@", _cmd, aNibPath);
+ return;
+ }
+
+ NSMutableArray* topLevelObjects = nil;
+ BOOL didInstantiate = [nib instantiateNibWithOwner:[[CatchAllNibLoader new] autorelease] topLevelObjects:&topLevelObjects];
+ if(!didInstantiate)
+ {
+ NSLog(@"%s failed to instantiate nib", _cmd);
+ }
+
+ NSLog(@"%s loaded nib with top levle objects %@", _cmd, topLevelObjects);
+ enumerate(topLevelObjects, id object)
+ {
+ if([object isKindOfClass:[NSWindow class]])
+ [object makeKeyAndOrderFront:self];
+ }
+}
+@end
+
+@implementation Dialog
+- (id)initWithPlugInController:(id <TMPlugInController>)aController
+{
+ NSApp = [NSApplication sharedApplication];
+ if(self = [super init])
+ {
+ NSConnection* connection = [NSConnection defaultConnection];
+ [connection setRootObject:[[DialogServer new] autorelease]];
+ if([connection registerName:@"TextMate dialog server"] == NO)
+ NSLog(@"couldn't setup TextMate dialog server."), NSBeep();
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+@end
50 Dialog.tmproj
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>currentDocument</key>
+ <string>Clock.mm</string>
+ <key>documents</key>
+ <array>
+ <dict>
+ <key>expanded</key>
+ <true/>
+ <key>name</key>
+ <string>Clock</string>
+ <key>regexFileFilter</key>
+ <string>!(/\.(?!htaccess)[^/]*|\.(tmproj|o|pyc|db)|/Icon\r)$</string>
+ <key>regexFolderFilter</key>
+ <string>!.*/(\.[^/]*|CVS|\{arch\}|build|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$</string>
+ <key>sourceDirectory</key>
+ <string></string>
+ </dict>
+ </array>
+ <key>fileHierarchyDrawerWidth</key>
+ <integer>200</integer>
+ <key>metaData</key>
+ <dict>
+ <key>Clock.mm</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>0</integer>
+ <key>line</key>
+ <integer>69</integer>
+ </dict>
+ <key>firstVisibleColumn</key>
+ <integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>42</integer>
+ </dict>
+ </dict>
+ <key>openDocuments</key>
+ <array>
+ <string>Clock.mm</string>
+ </array>
+ <key>showFileHierarchyDrawer</key>
+ <true/>
+ <key>windowFrame</key>
+ <string>{{417, 275}, {658, 660}}</string>
+</dict>
+</plist>
280 Dialog.xcodeproj/project.pbxproj
@@ -0,0 +1,280 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 177E4DA309132A0F0064163D /* Dialog.mm in Sources */ = {isa = PBXBuildFile; fileRef = 177E4DA209132A0F0064163D /* Dialog.mm */; };
+ 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 */
+ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 177E4DA109132A0F0064163D /* Dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dialog.h; sourceTree = "<group>"; };
+ 177E4DA209132A0F0064163D /* Dialog.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Dialog.mm; sourceTree = "<group>"; };
+ 32DBCF630370AF2F00C91783 /* Dialog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dialog_Prefix.pch; sourceTree = "<group>"; };
+ 8D5B49B6048680CD000E48DA /* Dialog.tmplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Dialog.tmplugin; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
+ D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+/* 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 /* Dialog */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AFFE84173DC02AAC07 /* Classes */,
+ 32C88E010371C26100C91783 /* Other Sources */,
+ 089C167CFE841241C02AAC07 /* Resources */,
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+ 19C28FB8FE9D52D311CA2CBB /* Products */,
+ );
+ name = Dialog;
+ sourceTree = "<group>";
+ };
+ 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+ 1058C7AEFEA557BF11CA2CBB /* Other 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 = (
+ 177E4DA209132A0F0064163D /* Dialog.mm */,
+ 177E4DA109132A0F0064163D /* Dialog.h */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 089C167FFE841241C02AAC07 /* AppKit.framework */,
+ D2F7E65807B2D6F200F64583 /* CoreData.framework */,
+ 089C1672FE841209C02AAC07 /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FB8FE9D52D311CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D5B49B6048680CD000E48DA /* Dialog.tmplugin */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 32C88E010371C26100C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32DBCF630370AF2F00C91783 /* Dialog_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D5B49AC048680CD000E48DA /* Dialog */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Dialog" */;
+ buildPhases = (
+ 8D5B49AF048680CD000E48DA /* Resources */,
+ 8D5B49B1048680CD000E48DA /* Sources */,
+ 8D5B49B3048680CD000E48DA /* Frameworks */,
+ 177E4DB50913322B0064163D /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Dialog;
+ productInstallPath = "$(HOME)/Library/Bundles";
+ productName = Dialog;
+ productReference = 8D5B49B6048680CD000E48DA /* Dialog.tmplugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 089C1669FE841209C02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Dialog" */;
+ hasScannedForEncodings = 1;
+ mainGroup = 089C166AFE841209C02AAC07 /* Dialog */;
+ projectDirPath = "";
+ targets = (
+ 8D5B49AC048680CD000E48DA /* Dialog */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D5B49AF048680CD000E48DA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 177E4DB50913322B0064163D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "mkdir -p \"$HOME/Library/Application Support/TextMate/PlugIns\"\ncp -pR \"${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}\" \"$HOME/Library/Application Support/TextMate/PlugIns\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D5B49B1048680CD000E48DA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 177E4DA309132A0F0064163D /* Dialog.mm 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 = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Dialog_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Library/Bundles";
+ PRODUCT_NAME = Dialog;
+ WRAPPER_EXTENSION = tmplugin;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ 1DEB913C08733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ ppc,
+ i386,
+ );
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Dialog_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Library/Bundles";
+ PRODUCT_NAME = Dialog;
+ WRAPPER_EXTENSION = tmplugin;
+ };
+ name = Release;
+ };
+ 1DEB913F08733D840010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Debug;
+ };
+ 1DEB914008733D840010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Dialog" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913B08733D840010E9CD /* Debug */,
+ 1DEB913C08733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Dialog" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB913F08733D840010E9CD /* Debug */,
+ 1DEB914008733D840010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
7 Dialog_Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'Clock' target in the 'Clock' project.
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
BIN English.lproj/InfoPlist.strings
Binary file not shown.
4 Example.nib/classes.nib
@@ -0,0 +1,4 @@
+{
+ IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; });
+ IBVersion = 1;
+}
16 Example.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>69 14 356 240 0 0 1920 1178 </string>
+ <key>IBFramework Version</key>
+ <string>446.1</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8L127</string>
+</dict>
+</plist>
BIN Example.nib/keyedobjects.nib
Binary file not shown.
26 Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//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>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.macromates.dialog_plug-in</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSPrincipalClass</key>
+ <string>Dialog</string>
+</dict>
+</plist>
162 tm_dialog.mm
@@ -0,0 +1,162 @@
+/*
+ g++ -Wmost -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -DDATE=\"`date +%Y-%m-%d`\" -Os "$TM_FILEPATH" -o ~/Library/tm/Support/bin/tm_dialog -framework Cocoa && strip ~/Library/tm/Support/bin/tm_dialog
+*/
+#import <Cocoa/Cocoa.h>
+#import <getopt.h>
+#import <fcntl.h>
+#import <stdio.h>
+#import <string.h>
+#import <stdlib.h>
+#import <unistd.h>
+#import <errno.h>
+#import <vector>
+
+char const* current_version ()
+{
+ char res[32];
+ return sscanf("$Revision: 1 $", "$%*[^:]: %s $", res) == 1 ? res : "???";
+}
+
+char const* AppName;
+
+@protocol TextMateDialogServerProtocol
+- (int)textMateDialogServerProtocolVersion;
+- (void)showNib:(NSString*)aNib withArguments:(id)someArguments;
+@end
+
+void contact_server (char const* nibName)
+{
+ id proxy = [NSConnection rootProxyForConnectionWithRegisteredName:@"TextMate dialog server" host:nil];
+ [proxy setProtocolForProxy:@protocol(TextMateDialogServerProtocol)];
+
+ if(!proxy)
+ {
+ fprintf(stderr, "%s: failed to establish connection with TextMate.\n", AppName);
+ }
+ else if([proxy textMateDialogServerProtocolVersion] >= 1)
+ {
+ [proxy showNib:[NSString stringWithUTF8String:nibName] withArguments:nil];
+ }
+ else
+ {
+ fprintf(stderr, "%s: you need to update this helper tool (server at version %d).\n", AppName, [proxy textMateDialogServerProtocolVersion]);
+ }
+}
+
+void usage ()
+{
+ std::vector<char> pad(10 - std::min(strlen(AppName), size_t(10)), ' ');
+ pad.push_back('\0');
+
+ char* buf = NULL;
+ int len = 0;
+ asprintf(&buf,
+ "%1$s r%2$s (" DATE ")\n"
+ "Usage: %1$s [-awl<number>rdnhv] [file ...]\n"
+ "Options:\n"
+ " -a, --async Do not wait for file to be closed by TextMate.\n"
+ " -w, --wait Wait for file to be closed by TextMate.\n"
+ " -l, --line <number> Place caret on line <number> after loading file.\n"
+ " -r, --recent Add file to Open Recent menu.\n"
+ " -d, --change-dir Change TextMates working directory to that of the file.\n"
+ " -n, --no-reactivation After edit with -w, do not re-activate the calling app.\n"
+ " -h, --help Show this information.\n"
+ " -v, --version Print version information.\n"
+ "\n"
+ "If multiple files are given, a project is created consisting of these\n"
+ "files, -a is then default and -w will be ignored (e.g. \"%1$s *.tex\").\n"
+ "\n%4$n"
+ "By default %1$s will not wait for the file to be closed\nexcept when used as filter:\n"
+ " ls *.tex|%1$s|sh%3$s-w implied\n"
+ " %1$s -|cat -n %3$s-w implied (read from stdin)\n"
+ "\n"
+ "An exception is made if the command is started as something which ends\nwith \"_wait\". "
+ "So to have a command with --wait as default, you can\ncreate a symbolic link like this:\n"
+ " ln -s %1$s %1$s_wait\n"
+ "\n", AppName, current_version(), &pad[0], &len
+ );
+
+ if(strstr(AppName, "_wait") == AppName + strlen(AppName) - 5)
+ buf[len] = '\0';
+ fprintf(stderr, "%s", buf);
+ free(buf);
+
+ exit(-1);
+}
+
+void version ()
+{
+ printf("%s r%s (" DATE ")\n", AppName, current_version());
+ exit(-1);
+}
+
+NSString* read_from_stdin ()
+{
+ NSString* res = nil;
+ char name[] = "/tmp/textmate stdin XXXXXX.txt";
+ int fd = mkstemps(name, 4);
+ if(fd != -1)
+ {
+ if(isatty(STDIN_FILENO) == 1)
+ fprintf(stderr, "%s: Reading from stdin... (press CTRL-D to proceed)\n", AppName);
+
+ char buf[1024];
+ while(size_t len = read(STDIN_FILENO, buf, sizeof(buf)))
+ write(fd, buf, len);
+ close(fd);
+
+ res = [[NSString stringWithUTF8String:name] stringByStandardizingPath];
+ }
+ return res;
+}
+
+int main (int argc, char* argv[])
+{
+#if 0
+ extern char* optarg;
+ extern int optind;
+#endif
+ if(AppName = strrchr(argv[0], '/'))
+ AppName++;
+ else AppName = argv[0];
+#if 0
+ static struct option const longopts[] = {
+ { "async", no_argument, 0, 'a' },
+ { "wait", no_argument, 0, 'w' },
+ { "line", required_argument, 0, 'l' },
+ { "recent", no_argument, 0, 'r' },
+ { "change-dir", no_argument, 0, 'd' },
+ { "no-reactivation", no_argument, 0, 'n' },
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { 0, 0, 0, 0 }
+ };
+
+ while((ch = getopt_long(argc, argv, "awrdnhvl:", longopts, NULL)) != -1)
+ {
+ switch(ch)
+ {
+ case 'a': should_wait = false; break;
+ case 'w': should_wait = true; break;
+ case 'l': line = atoi(optarg); break;
+ case 'r': add_to_recent = true; break;
+ case 'd': change_dir = true; break;
+ case 'n': reactivate = false; break;
+ case 'h': usage(); break;
+ case 'v': version(); break;
+ default: usage(); break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+#endif
+
+ NSAutoreleasePool* pool = [NSAutoreleasePool new];
+ NSApp = [NSApplication sharedApplication];
+
+ contact_server(argc == 2 ? argv[1] : "foo");
+
+ [pool release];
+ return 0;
+}

0 comments on commit b06f34c

Please sign in to comment.
Something went wrong with that request. Please try again.