Skip to content

output and help #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions Commands/alert.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,65 @@ - (void)handleCommand:(CLIProxy*)proxy
[alert setMessageText:msg];
if(NSString* txt = [args objectForKey:@"body"])
[alert setInformativeText:txt];
if(NSString* sup = [args objectForKey:@"suppression"])
{
[alert setShowsSuppressionButton:YES];
[[alert suppressionButton] setTitle:sup];
}

if(NSString* iconPath = [args objectForKey:@"icon"])
{
NSImage *icon = nil;
iconPath = [iconPath stringByResolvingSymlinksInPath];
BOOL isDir = NO;
if([[NSFileManager defaultManager] fileExistsAtPath:iconPath isDirectory:&isDir] && !isDir)
{
icon = [[NSImage alloc] initByReferencingFile:iconPath];
if(icon && [icon isValid])
{
[alert setIcon:icon];
[icon release];
}
}
else if(icon = [NSImage imageNamed:iconPath])
[alert setIcon:icon];
else if(icon = [NSImage imageNamed:[iconPath stringByReplacingOccurrencesOfString:@"ImageName" withString:@""]])
[alert setIcon:icon];

if(!icon)
fprintf(stderr, "Passed icon path or named image '%s' not found.\n", [iconPath UTF8String]);

}

int i = 0;
while(NSString* button = [args objectForKey:[NSString stringWithFormat:@"button%d", ++i]])
[alert addButtonWithTitle:button];

int alertResult = ([alert runModal] - NSAlertFirstButtonReturn);
NSDictionary* resultDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:alertResult] forKey:@"buttonClicked"];
NSMutableDictionary* resultDict = [NSMutableDictionary dictionary];
[resultDict setObject:[NSNumber numberWithInt:alertResult] forKey:@"buttonClicked"];
if([args objectForKey:@"suppression"])
[resultDict setObject:[NSNumber numberWithInt:[[alert suppressionButton] state]] forKey:@"suppressionButtonState"];

[TMDCommand writePropertyList:resultDict toFileHandle:[proxy outputHandle]];
[TMDCommand writePropertyList:resultDict toFileHandle:[proxy outputHandle] withProxy:proxy];
}

- (NSString *)commandDescription
{
return @"Show an alert box.";
return @"Shows a customizable alert box and returns the index of the chosen button - counting from the right.";
}

- (NSString *)usageForInvocation:(NSString *)invocation;
{
return [NSString stringWithFormat:@"\t%1$@ --alertStyle warning --title 'Delete File?' --body 'You cannot undo this action.' --button1 Delete --button2 Cancel\n", invocation];
return [NSString stringWithFormat:
@"\t%1$@ --alertStyle critical --title 'Delete File?' --body 'You cannot undo this action.' --button1 Delete --button2 Cancel\n"
@"\t%1$@ --filter buttonClicked --title 'Delete File?' --body 'You cannot undo this action.' --button1 Delete --button2 Cancel\n"
@"\t%1$@ --icon NSUserAccounts --title 'Delete Account?' --body 'You cannot undo this action.' --button1 Delete --button2 Cancel\n"
@"\t%1$@ --icon '~/Pictures/iChat Icons/Flags/Denmark.png' --title 'First Run?' --body 'Please note this.' --suppression 'Do not show this again'\n"
@"\nOption:\n"
@"\t--alertStyle {informational, warning, critical}\n"
@"\t\t if not specified the default style is 'informational'\n"
@"\t--icon «image path or known image name»\n"
@"\t--suppression «title»\n", invocation];
}
@end
4 changes: 2 additions & 2 deletions Commands/defaults.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ - (void)handleCommand:(CLIProxy*)proxy
if(NSString* key = [args objectForKey:@"read"])
{
if(id obj = [[NSUserDefaults standardUserDefaults] objectForKey:key])
[TMDCommand writePropertyList:obj toFileHandle:[proxy outputHandle]];
[TMDCommand writePropertyList:obj toFileHandle:[proxy outputHandle] withProxy:proxy];
}
}

- (NSString *)commandDescription
{
return @"Register default values for user settings.";
return @"Registers default values for user settings.";
}

- (NSString *)usageForInvocation:(NSString *)invocation;
Expand Down
29 changes: 19 additions & 10 deletions Commands/help.mm
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,38 @@ - (NSString *)commandDescription

- (NSString *)usageForInvocation:(NSString *)invocation;
{
return [NSString stringWithFormat:@"%@ help [command]", invocation];
return [NSString stringWithFormat:@"\t%1$@ [«command»]\n", invocation];
}

- (NSString *)commandSummaryText
{
NSDictionary *commands = [TMDCommand registeredCommands];

NSArray *sortedItems = [[commands allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

NSMutableString *help = [NSMutableString stringWithCapacity:100];

int commandCount = 0;
for(NSEnumerator *enumerator = [commands keyEnumerator]; NSString *commandName = [enumerator nextObject]; )
NSInteger commandCount = 0;
for(NSString *commandName in sortedItems)
{
if(![commandName hasPrefix:@"x-"])
{
++commandCount;
TMDCommand *command = [commands objectForKey:commandName];
NSString *description = [command commandDescription];
[help appendFormat:@"\t%@: %@\n", commandName, description];
NSString *description = [[(TMDCommand*)[commands objectForKey:commandName] commandDescription]
stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t\t"];
[help appendFormat:@"\t%@\n\t\t%@\n", commandName, description];
}
}
[help insertString:[NSString stringWithFormat:@"%d commands registered:\n", commandCount] atIndex:0];
[help insertString:[NSString stringWithFormat:@"%ld commands registered:\n", commandCount] atIndex:0];

[help appendString:@"Use `\"$DIALOG\" help command` for detailed help\n"];
[help appendString:@"\nUse `\"$DIALOG\" help command` for detailed help\n\n"];
[help appendString:
@"Options:\n"
@"\t--filter <key>\n"
@"\t--filter <plist array of keys>\n"
@"\t\tFor commands returning a property list as default specify the <key(s)>\n"
@"\t\twhose value(s) should be outputted as plain string\n"
@"\t\tseparated by a new line character.\n"
@"\t\tIf a passed <key> doesn't exist it returns an empty string.\n"];

return help;
}
Expand All @@ -57,7 +66,7 @@ - (NSString *)helpForCommand:(NSString *)commandName
if(![commandName hasPrefix:@"x-"] && (command = [TMDCommand objectForCommand:commandName]))
{
[help appendFormat:@"%@\n\n",[command commandDescription]];
[help appendFormat:@"%@ usage:\n",commandName];
[help appendFormat:@"'%@' usage:\n",commandName];
[help appendFormat:@"%@\n",[command usageForInvocation:[NSString stringWithFormat:@"\"$DIALOG\" %@", commandName]]];
}
else
Expand Down
2 changes: 1 addition & 1 deletion Commands/images.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ - (void)handleCommand:(CLIProxy*)proxy

- (NSString *)commandDescription
{
return @"Add image files as named images for use by other commands/nibs.";
return @"Adds image files as named images for use by other commands/nibs.";
}

- (NSString *)usageForInvocation:(NSString *)invocation;
Expand Down
124 changes: 96 additions & 28 deletions Commands/menu.mm
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#import <Carbon/Carbon.h>
#import "../Dialog2.h"
#import "../TMDCommand.h"
#import "Utilities/TextMate.h" // -positionForWindowUnderCaret
Expand All @@ -12,31 +11,43 @@
"$DIALOG" menu --items '({title = "foo"; header = 1;},{title = "bar";})'
*/

#define kMenuTitleKey @"title"
#define kMenuItemsKey @"items"
#define kMenuSeparatorKey @"separator"
#define kMenuHeaderKey @"header"
#define kMenuMenuKey @"menu"

@interface DialogPopupMenuTarget : NSObject
{
NSInteger selectedIndex;
NSDictionary *selectedObject;
}
@property NSInteger selectedIndex;
@property (nonatomic, retain) NSDictionary *selectedObject;
@end

@implementation DialogPopupMenuTarget
@synthesize selectedIndex;
@synthesize selectedObject;
- (id)init
{
if((self = [super init]))
self.selectedIndex = NSNotFound;
self.selectedObject = nil;
return self;
}

- (BOOL)validateMenuItem:(NSMenuItem*)menuItem
{
return [menuItem action] == @selector(takeSelectedItemIndexFrom:);
return [menuItem action] == @selector(takeSelectedItemFrom:);
}

- (void)takeSelectedItemIndexFrom:(id)sender
- (void)takeSelectedItemFrom:(id)sender
{
NSAssert([sender isKindOfClass:[NSMenuItem class]], @"Unexpected sender for menu target");
self.selectedIndex = [(NSMenuItem*)sender tag];
self.selectedObject = [(NSMenuItem*)sender representedObject];
}

- (void)dealloc
{
if(selectedObject) [selectedObject release];
[super dealloc];
}
@end

Expand All @@ -48,23 +59,26 @@ @interface TMDMenuCommand : TMDCommand
@implementation TMDMenuCommand
+ (void)load
{
[TMDCommand registerObject:[self new] forCommand:@"menu"];
[TMDCommand registerObject:[self new] forCommand:kMenuMenuKey];
}

- (NSString *)commandDescription
{
return @"Presents a menu using the given structure and returns the option chosen by the user";
return @"Presents a menu using the given structure and returns the underlying object chosen by the user.";
}

- (NSString *)usageForInvocation:(NSString *)invocation;
{
return [NSString stringWithFormat:@"\t%1$@ --items '({title = foo;}, {separator = 1;}, {header=1; title = bar;}, {title = baz;})'\n", invocation];
return [NSString stringWithFormat:@"\
%1$@ --items '({title = foo;}, {separator = 1;}, {header=1; title = bar;}, {title = baz;})'\n\
%1$@ --items '({title = foo;}, {separator = 1;}, {header=1; title = bar1;}, {title = baz; ofHeader = bar1;}, {header=1; title = bar2;}, {title = baz; ofHeader = bar2;}, {menu = { title = aSubmenu; items = ( {title = baz; ofSubmenu = aSubmenu;}, {separator = 1;}, {header=1; title = bar2;}, {title = subbaz;} ); };})'\n",
invocation];
}

- (void)handleCommand:(CLIProxy*)proxy
{
NSDictionary* args = [proxy parameters];
NSArray* menuItems = [args objectForKey:@"items"];
NSArray* menuItems = [args objectForKey:kMenuItemsKey];

// FIXME this is needed only because we presently can’t express argument constraints (CLIProxy would otherwise correctly validate/convert CLI arguments)
if([menuItems isKindOfClass:[NSString class]])
Expand All @@ -74,31 +88,84 @@ - (void)handleCommand:(CLIProxy*)proxy
[menu setFont:[NSFont menuFontOfSize:([[NSUserDefaults standardUserDefaults] integerForKey:@"OakBundleManagerDisambiguateMenuFontSize"] ?: [NSFont smallSystemFontSize])]];
DialogPopupMenuTarget* menuTarget = [[[DialogPopupMenuTarget alloc] init] autorelease];

int item_id = 0;
bool in_section = false;
NSInteger item_id_key = 0;
BOOL in_section = false;

enumerate(menuItems, NSDictionary* menuItem)
{
if([[menuItem objectForKey:@"separator"] intValue])
// check for separator
if([[menuItem objectForKey:kMenuSeparatorKey] intValue])
{
[menu addItem:[NSMenuItem separatorItem]];
}
else if([[menuItem objectForKey:@"header"] intValue])
// check for header and indent following items
else if([[menuItem objectForKey:kMenuHeaderKey] intValue])
{
[menu addItemWithTitle:[menuItem objectForKey:@"title"] action:NULL keyEquivalent:@""];
in_section = true;
if(NSString *item = [menuItem objectForKey:kMenuTitleKey])
{
[menu addItemWithTitle:item action:NULL keyEquivalent:@""];
in_section = true;
}
}
// check for a submenu
else if(NSDictionary *aSubMenu = [menuItem objectForKey:kMenuMenuKey])
{
if([aSubMenu objectForKey:kMenuTitleKey] &&
[aSubMenu objectForKey:kMenuItemsKey] &&
[[aSubMenu objectForKey:kMenuItemsKey] isKindOfClass:[NSArray class]])
{
NSArray *subMenuItems = (NSArray*)[aSubMenu objectForKey:kMenuItemsKey];
NSMenu* submenu = [[[NSMenu alloc] init] autorelease];
[submenu setFont:[NSFont menuFontOfSize:([[NSUserDefaults standardUserDefaults] integerForKey:@"OakBundleManagerDisambiguateMenuFontSize"] ?: [NSFont smallSystemFontSize])]];

NSString *submenuTitle = [aSubMenu objectForKey:kMenuTitleKey];
BOOL subin_section = false;

enumerate(subMenuItems, NSDictionary* menuItem)
{
if([[menuItem objectForKey:kMenuSeparatorKey] intValue])
{
[submenu addItem:[NSMenuItem separatorItem]];
}
else if([[menuItem objectForKey:kMenuHeaderKey] intValue])
{
if(NSString *item = [menuItem objectForKey:kMenuTitleKey])
{
[submenu addItemWithTitle:item action:NULL keyEquivalent:@""];
subin_section = true;
}
}
else if(NSString *item = [menuItem objectForKey:kMenuTitleKey])
{
NSMenuItem* theItem = [submenu addItemWithTitle:item action:@selector(takeSelectedItemFrom:) keyEquivalent:@""];
[theItem setTarget:menuTarget];
[theItem setRepresentedObject:menuItem];
if(subin_section)
[theItem setIndentationLevel:1];
}
}
NSMenuItem* subMenuItem = [[NSMenuItem alloc] initWithTitle:submenuTitle action:NULL keyEquivalent:@""];
[subMenuItem setSubmenu:submenu];
[menu addItem:subMenuItem];
[subMenuItem release];
}
}
// check for items specified by the key 'title'
else
{
NSMenuItem* theItem = [menu addItemWithTitle:[menuItem objectForKey:@"title"] action:@selector(takeSelectedItemIndexFrom:) keyEquivalent:@""];
[theItem setTarget:menuTarget];
[theItem setTag:item_id];
if(++item_id <= 10)
if(NSString *item = [menuItem objectForKey:kMenuTitleKey])
{
[theItem setKeyEquivalent:[NSString stringWithFormat:@"%d", item_id % 10]];
[theItem setKeyEquivalentModifierMask:0];
NSMenuItem* theItem = [menu addItemWithTitle:item action:@selector(takeSelectedItemFrom:) keyEquivalent:@""];
[theItem setTarget:menuTarget];
[theItem setRepresentedObject:menuItem];
if(++item_id_key <= 10)
{
[theItem setKeyEquivalent:[NSString stringWithFormat:@"%ld", item_id_key % 10]];
[theItem setKeyEquivalentModifierMask:0];
}
if(in_section)
[theItem setIndentationLevel:1];
}
if (in_section)
[theItem setIndentationLevel:1];
}
}

Expand All @@ -107,7 +174,8 @@ - (void)handleCommand:(CLIProxy*)proxy
pos = [textView positionForWindowUnderCaret];


if([menu popUpMenuPositioningItem:nil atLocation:pos inView:nil] && menuTarget.selectedIndex != NSNotFound)
[TMDCommand writePropertyList:[menuItems objectAtIndex:menuTarget.selectedIndex] toFileHandle:[proxy outputHandle]];
if([menu popUpMenuPositioningItem:nil atLocation:pos inView:nil] && menuTarget.selectedObject)
[TMDCommand writePropertyList:menuTarget.selectedObject toFileHandle:[proxy outputHandle] withProxy:proxy];

}
@end
2 changes: 1 addition & 1 deletion Commands/nib/TMDNibController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ - (void)return:(NSDictionary*)eventInfo
nil];

enumerate(clientFileHandles, NSFileHandle* fileHandle)
[TMDCommand writePropertyList:res toFileHandle:fileHandle];
[TMDCommand writePropertyList:res toFileHandle:fileHandle withProxy:NULL];

[clientFileHandles removeAllObjects];
}
Expand Down
10 changes: 5 additions & 5 deletions Commands/nib/nib.mm
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ - (NSString *)commandDescription
- (NSString *)usageForInvocation:(NSString *)invocation;
{
return [NSString stringWithFormat:
@"%1$@ --load «nib file» [«options»]\n"
@"%1$@ --update «token» [«options»]\n"
@"%1$@ --wait «token»\n"
@"%1$@ --dispose «token»\n"
@"%1$@ --list\n"
@"\t%1$@ --load «nib file» [«options»]\n"
@"\t%1$@ --update «token» [«options»]\n"
@"\t%1$@ --wait «token»\n"
@"\t%1$@ --dispose «token»\n"
@"\t%1$@ --list\n"
@"\nOptions:\n"
@"\t--center\n"
@"\t--model «plist»\n",
Expand Down
13 changes: 11 additions & 2 deletions Commands/popup/popup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,21 @@ - (void)handleCommand:(CLIProxy*)proxy

- (NSString *)commandDescription
{
return @"Presents the user with a list of items which can be filtered down by typing to select the item they want.";
return @"Presents the user with a list of items which can be filtered down by typing.";
}

- (NSString *)usageForInvocation:(NSString *)invocation;
{
return [NSString stringWithFormat:@"\t%1$@ --suggestions '( { display = law; }, { display = laws; insert = \"(${1:hello}, ${2:again})\"; } )'\n", invocation];
return [NSString stringWithFormat:
@"\t%1$@ --suggestions '( { display = law; }, { display = laws; insert = \"(${1:hello}, ${2:again})\"; } )'\n\n"
@"\tThe chosen item given by the key “display” or, if the “insert” key is specified,\n"
@"\tthe content of that key which also can be a snippet will be inserted into the front-most document.\n\n"
@"Options:\n"
@"\t--alreadyTyped «string»\n"
@"\t--staticPrefix «string»\n"
@"\t--additionalWordCharacters «string»\n"
@"\t--returnChoice «boolean»\n"
@"\t--caseInsensitive «boolean»\n", invocation];
}

@end
Loading