mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
Refactor the gitx CLI to use apple events and the scripting bridge
Sending the arguments with the openURL:... message allows the repository document to modify it's UI without the UI flashing between states as it opens.
Covers all the existing functionality of the CLI, but modifies:
- "--all" "--local" "--branch" change the branch filter
- cleaned up the usage (help) text and added info on missing commands
- looks up the full ref name of refs so the name of a branch or tag can be entered (the user can enter "master" instead of "refs/heads/master")
Modified the History Controller to watch for and react to branch filter changes.
The GitX.h file is generated by the 'sdp' tool in a run script build phase called 'Generate Scripting Bridge Header' based on the content of GitX.sdef. It is used by the Scripting Bridge so that other apps (in this case the gitx CLI) can call Applescript commands on GitX in objective-c.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#import "PBRemoteProgressSheet.h"
|
||||
#import "PBGitRevList.h"
|
||||
#import "PBGitDefaults.h"
|
||||
#import "GitXScriptingConstants.h"
|
||||
|
||||
NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
|
||||
@@ -429,6 +430,31 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// useful for getting the full ref for a user entered name
|
||||
// EX: name: master
|
||||
// ref: refs/heads/master
|
||||
- (PBGitRef *)refForName:(NSString *)name
|
||||
{
|
||||
if (!name)
|
||||
return nil;
|
||||
|
||||
int retValue = 1;
|
||||
NSString *output = [self outputInWorkdirForArguments:[NSArray arrayWithObjects:@"show-ref", name, nil] retValue:&retValue];
|
||||
if (retValue)
|
||||
return nil;
|
||||
|
||||
// the output is in the format: <SHA-1 ID> <space> <reference name>
|
||||
// with potentially multiple lines if there are multiple matching refs (ex: refs/remotes/origin/master)
|
||||
// here we only care about the first match
|
||||
NSArray *refList = [output componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if ([refList count] > 1) {
|
||||
NSString *refName = [refList objectAtIndex:1];
|
||||
return [PBGitRef refFromString:refName];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Returns either this object, or an existing, equal object
|
||||
- (PBGitRevSpecifier*) addBranch:(PBGitRevSpecifier*)branch
|
||||
@@ -876,6 +902,113 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
|
||||
}
|
||||
|
||||
|
||||
#pragma mark GitX Scripting
|
||||
|
||||
- (void)handleRevListArguments:(NSArray *)arguments
|
||||
{
|
||||
if (![arguments count])
|
||||
return;
|
||||
|
||||
PBGitRevSpecifier *revListSpecifier = nil;
|
||||
|
||||
// the argument may be a branch or tag name but will probably not be the full reference
|
||||
if ([arguments count] == 1) {
|
||||
PBGitRef *refArgument = [self refForName:[arguments lastObject]];
|
||||
if (refArgument)
|
||||
revListSpecifier = [[PBGitRevSpecifier alloc] initWithRef:refArgument];
|
||||
}
|
||||
|
||||
if (!revListSpecifier)
|
||||
revListSpecifier = [[PBGitRevSpecifier alloc] initWithParameters:arguments];
|
||||
|
||||
self.currentBranch = [self addBranch:revListSpecifier];
|
||||
[PBGitDefaults setShowStageView:NO];
|
||||
[self.windowController showHistoryView:self];
|
||||
}
|
||||
|
||||
- (void)handleBranchFilterEventForFilter:(PBGitXBranchFilterType)filter additionalArguments:(NSMutableArray *)arguments
|
||||
{
|
||||
self.currentBranchFilter = filter;
|
||||
[PBGitDefaults setShowStageView:NO];
|
||||
[self.windowController showHistoryView:self];
|
||||
|
||||
// treat any additional arguments as a rev-list specifier
|
||||
if ([arguments count] > 1) {
|
||||
[arguments removeObjectAtIndex:0];
|
||||
[self handleRevListArguments:arguments];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleGitXScriptingArguments:(NSAppleEventDescriptor *)argumentsList
|
||||
{
|
||||
NSMutableArray *arguments = [NSMutableArray array];
|
||||
uint argumentsIndex = 1; // AppleEvent list descriptor's are one based
|
||||
while(1) {
|
||||
NSAppleEventDescriptor *arg = [argumentsList descriptorAtIndex:argumentsIndex++];
|
||||
if (arg)
|
||||
[arguments addObject:[arg stringValue]];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (![arguments count])
|
||||
return;
|
||||
|
||||
NSString *firstArgument = [arguments objectAtIndex:0];
|
||||
|
||||
if ([firstArgument isEqualToString:@"-c"] || [firstArgument isEqualToString:@"--commit"]) {
|
||||
[PBGitDefaults setShowStageView:YES];
|
||||
[self.windowController showCommitView:self];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([firstArgument isEqualToString:@"--all"]) {
|
||||
[self handleBranchFilterEventForFilter:kGitXAllBranchesFilter additionalArguments:arguments];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([firstArgument isEqualToString:@"--local"]) {
|
||||
[self handleBranchFilterEventForFilter:kGitXLocalRemoteBranchesFilter additionalArguments:arguments];
|
||||
return;
|
||||
}
|
||||
|
||||
if ([firstArgument isEqualToString:@"--branch"]) {
|
||||
[self handleBranchFilterEventForFilter:kGitXSelectedBranchFilter additionalArguments:arguments];
|
||||
return;
|
||||
}
|
||||
|
||||
// if the argument is not a known command then treat it as a rev-list specifier
|
||||
[self handleRevListArguments:arguments];
|
||||
}
|
||||
|
||||
// see if the current appleEvent has the command line arguments from the gitx cli
|
||||
// this could be from an openApplication or an openDocument apple event
|
||||
// when opening a repository this is called before the sidebar controller gets it's awakeFromNib: message
|
||||
// if the repository is already open then this is also a good place to catch the event as the window is about to be brought forward
|
||||
- (void)showWindows
|
||||
{
|
||||
NSAppleEventDescriptor *currentAppleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
|
||||
|
||||
if (currentAppleEvent) {
|
||||
NSAppleEventDescriptor *eventRecord = [currentAppleEvent paramDescriptorForKeyword:keyAEPropData];
|
||||
|
||||
// on app launch there may be many repositories opening, so double check that this is the right repo
|
||||
NSString *path = [[eventRecord paramDescriptorForKeyword:typeFileURL] stringValue];
|
||||
if (path) {
|
||||
if ([[PBGitRepository gitDirForURL:[NSURL URLWithString:path]] isEqual:[self fileURL]]) {
|
||||
NSAppleEventDescriptor *argumentsList = [eventRecord paramDescriptorForKeyword:kGitXAEKeyArgumentsList];
|
||||
[self handleGitXScriptingArguments:argumentsList];
|
||||
|
||||
// showWindows may be called more than once during app launch so remove the CLI data after we handle the event
|
||||
[currentAppleEvent removeDescriptorWithKeyword:keyAEPropData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[super showWindows];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark low level
|
||||
|
||||
- (int) returnValueForCommand:(NSString *)cmd
|
||||
|
||||
Reference in New Issue
Block a user