diff --git a/GLFileView.m b/GLFileView.m
index dcedd3a..7fc7fe3 100644
--- a/GLFileView.m
+++ b/GLFileView.m
@@ -20,6 +20,10 @@
@interface GLFileView ()
- (void)saveSplitViewPosition;
++ (NSString *)parseDiffBlock:(NSString *)txt;
++ (NSString *)parseDiffHeader:(NSString *)txt;
++ (NSString *)parseDiffChunk:(NSString *)txt;
++ (NSString *)parseBinaryDiff:(NSString *)txt;
@end
@@ -120,11 +124,12 @@
if(!theError){
NSString *filePath = [file fullPath];
fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
- fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA}" withString:file.sha];
+ NSLog(@"file.sha='%@'",file.sha);
+ fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA_PREV}" withString:file.sha];
if(diffType==@"h") {
- fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA2}" withString:@"HEAD"];
+ fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA}" withString:@"HEAD"];
}else {
- fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA2}" withString:@"--"];
+ fileTxt=[fileTxt stringByReplacingOccurrencesOfString:@"{SHA}" withString:@"--"];
}
[script callWebScriptMethod:@"showFile" withArguments:[NSArray arrayWithObjects:fileTxt, filePath, nil]];
}else{
@@ -287,245 +292,291 @@
+ (NSString *)parseDiff:(NSString *)txt
{
txt=[self parseHTML:txt];
-
- NSArray *lines = [txt componentsSeparatedByString:@"\n"];
- NSString *line;
+
NSMutableString *res=[NSMutableString string];
+ NSScanner *scan=[NSScanner scannerWithString:txt];
+ NSString *block;
- int l_line,l_end;
- int r_line,r_end;
+ [scan scanUpToString:@"diff --git" intoString:NULL]; //move to first diff
- int i=0;
- do {
- line=[lines objectAtIndex:i];
- if([GLFileView isStartDiff:line]){
- NSString *fileName=[self getFileName:line];
- [res appendString:[NSString stringWithFormat:@"
",fileName]];
- do{
- [res appendString:[NSString stringWithFormat:@" %@ ",line]];
- line=nil;
- if (i<([lines count]-1))
- line = [lines objectAtIndex:++i];
- }while([GLFileView isDiffHeader:line]);
- [res appendString:@" "];
- if(![self isBinaryFile:line]){
- [res appendString:[NSString stringWithFormat:@"",fileName]];
- }
- [res appendString:@" |
"];
+ while([scan scanString:@"diff --git" intoString:NULL]){ // is a diff start?
+ [scan scanUpToString:@"diff --git" intoString:&block];
+ [res appendString:[GLFileView parseDiffBlock:[NSString stringWithFormat:@"diff --git %@",block]]];
+ }
+
+ return res;
+}
- if (!line)
- break; // do nothing, this is probably header-only diff (permissions change, maybe)
-
- if([self isBinaryFile:line]){
- NSArray *files=[self getFilesNames:line];
- if(![[files objectAtIndex:0] isAbsolutePath]){
- [res appendString:[NSString stringWithFormat:@"| %@ |
",[files objectAtIndex:0]]];
- if([GLFileView isImage:[files objectAtIndex:0]]){
- [res appendString:[NSString stringWithFormat:@" |
",[files objectAtIndex:0]]];
- }
- }
- if(![[files objectAtIndex:1] isAbsolutePath]){
- [res appendString:[NSString stringWithFormat:@"| %@ |
",[files objectAtIndex:1]]];
- if([GLFileView isImage:[files objectAtIndex:1]]){
- [res appendString:[NSString stringWithFormat:@" |
",[files objectAtIndex:1]]];
- }
- }
- }else{
- do{
- NSString *header=[line substringFromIndex:3];
- NSRange hr = NSMakeRange(0, [header rangeOfString:@" @@"].location);
- header=[header substringWithRange:hr];
-
- NSArray *pos=[header componentsSeparatedByString:@" "];
- NSArray *pos_l=[[pos objectAtIndex:0] componentsSeparatedByString:@","];
- NSArray *pos_r=[[pos objectAtIndex:1] componentsSeparatedByString:@","];
-
- l_end=l_line=abs([[pos_l objectAtIndex:0]integerValue]);
- if ([pos_l count]>1) {
- l_end=l_line+[[pos_l objectAtIndex:1]integerValue];
- }
-
- r_end=r_line=[[pos_r objectAtIndex:0]integerValue];
- if ([pos_r count]>1) {
- r_end=r_line+[[pos_r objectAtIndex:1]integerValue];
- }
-
- [res appendString:[NSString stringWithFormat:@"",line]];
- do{
- line=[lines objectAtIndex:++i];
- NSString *s=[line substringToIndex:1];
- if([s isEqualToString:@" "]){
- [res appendString:[NSString stringWithFormat:@"| %d | %d | ",l_line++,r_line++]];
- }else if([s isEqualToString:@"-"]){
- [res appendString:[NSString stringWithFormat:@"
| %d | | ",l_line++]];
- }else if([s isEqualToString:@"+"]){
- [res appendString:[NSString stringWithFormat:@"
| %d | ",r_line++]];
- }
- if(![s isEqualToString:@"\\"]){
- [res appendString:[NSString stringWithFormat:@"%@ |
",[line substringFromIndex:1]]];
- }
- }while((l_line
"];
- }else {
- i++;
- }
- }while(i<[lines count]);
-
- return res;
++ (NSString *)parseDiffBlock:(NSString *)txt
+{
+ NSMutableString *res=[NSMutableString string];
+ NSScanner *scan=[NSScanner scannerWithString:txt];
+ NSString *block;
+
+ [scan scanUpToString:@"\n@@ " intoString:&block];
+ [res appendString:@""];
+ [res appendString:[GLFileView parseDiffHeader:block]];
+ [res appendString:@""];
+
+ if([txt rangeOfString:@"Binary files"].location!=NSNotFound){
+ [res appendString:[GLFileView parseBinaryDiff:block]];
+ }
+
+ while([scan scanString:@"@@ " intoString:NULL]){
+ [scan scanUpToString:@"\n@@ " intoString:&block];
+ [res appendString:[GLFileView parseDiffChunk:[NSString stringWithFormat:@"@@ %@",block]]];
+ }
+
+ [res appendString:@"
"];
+
+ return res;
+}
+
++ (NSString *)parseBinaryDiff:(NSString *)txt
+{
+ NSMutableString *res=[NSMutableString string];
+ NSScanner *scan=[NSScanner scannerWithString:txt];
+ NSString *block;
+
+ [scan scanUpToString:@"Binary files" intoString:NULL];
+ [scan scanUpToString:@"" intoString:&block];
+
+ NSArray *files=[self getFilesNames:block];
+ [res appendString:@""];
+ [res appendString:[NSString stringWithFormat:@"%@ ",[files objectAtIndex:0]]];
+ if(![[files objectAtIndex:0] isAbsolutePath]){
+ if([GLFileView isImage:[files objectAtIndex:0]]){
+ [res appendString:[NSString stringWithFormat:@" ",[files objectAtIndex:0]]];
+ }
+ }
+ [res appendString:@" | => | "];
+ [res appendString:[NSString stringWithFormat:@"%@ ",[files objectAtIndex:1]]];
+ if(![[files objectAtIndex:1] isAbsolutePath]){
+ if([GLFileView isImage:[files objectAtIndex:1]]){
+ [res appendString:[NSString stringWithFormat:@" ",[files objectAtIndex:1]]];
+ }
+ }
+ [res appendString:@" |
"];
+
+ return res;
+}
+
++ (NSString *)parseDiffChunk:(NSString *)txt
+{
+ NSEnumerator *lines = [[txt componentsSeparatedByString:@"\n"] objectEnumerator];
+ NSMutableString *res=[NSMutableString string];
+
+ NSString *line;
+ int l_line,l_end;
+ int r_line,r_end;
+
+ line=[lines nextObject];
+ NSLog(@"-=%@=-",line);
+ NSString *header=[line substringFromIndex:3];
+ NSRange hr = NSMakeRange(0, [header rangeOfString:@" @@"].location);
+ header=[header substringWithRange:hr];
+
+ NSArray *pos=[header componentsSeparatedByString:@" "];
+ NSArray *pos_l=[[pos objectAtIndex:0] componentsSeparatedByString:@","];
+ NSArray *pos_r=[[pos objectAtIndex:1] componentsSeparatedByString:@","];
+
+ l_end=l_line=abs([[pos_l objectAtIndex:0]integerValue]);
+ if ([pos_l count]>1) {
+ l_end=l_line+[[pos_l objectAtIndex:1]integerValue];
+ }
+
+ r_end=r_line=[[pos_r objectAtIndex:0]integerValue];
+ if ([pos_r count]>1) {
+ r_end=r_line+[[pos_r objectAtIndex:1]integerValue];
+ }
+
+ [res appendString:[NSString stringWithFormat:@"",line]];
+ do{
+ line=[lines nextObject];
+ NSString *s=[line substringToIndex:1];
+ if([s isEqualToString:@" "]){
+ [res appendString:[NSString stringWithFormat:@"| %d | %d | ",l_line++,r_line++]];
+ }else if([s isEqualToString:@"-"]){
+ [res appendString:[NSString stringWithFormat:@"
| %d | | ",l_line++]];
+ }else if([s isEqualToString:@"+"]){
+ [res appendString:[NSString stringWithFormat:@"
| %d | ",r_line++]];
+ }
+ if(![s isEqualToString:@"\\"]){
+ [res appendString:[NSString stringWithFormat:@"%@ |
",[line substringFromIndex:1]]];
+ }
+ }while((l_line",fileName]];
+ do{
+ [res appendString:[NSString stringWithFormat:@" %@ ",line]];
+ }while((line=[lines nextObject]));
+ [res appendString:@" "];
+
+ if([txt rangeOfString:@"Binary files"].location==NSNotFound){
+ [res appendString:[NSString stringWithFormat:@"",fileName]];
+ }
+
+ [res appendString:@" | "];
+
+ return res;
}
+(NSString *)getFileName:(NSString *)line
{
- NSRange b = [line rangeOfString:@"b/"];
- NSString *file=[line substringFromIndex:b.location+2];
- return file;
+ NSRange b = [line rangeOfString:@"b/"];
+ NSString *file=[line substringFromIndex:b.location+2];
+ return file;
}
+(NSArray *)getFilesNames:(NSString *)line
{
- NSString *a = nil;
- NSString *b = nil;
- NSScanner *scanner=[NSScanner scannerWithString:line];
- if([scanner scanString:@"Binary files " intoString:NULL]){
- [scanner scanUpToString:@" and" intoString:&a];
- [scanner scanString:@"and" intoString:NULL];
- [scanner scanUpToString:@" differ" intoString:&b];
- }
- if (![a isAbsolutePath]) {
- a=[a substringFromIndex:2];
- }
- if (![b isAbsolutePath]) {
- b=[b substringFromIndex:2];
- }
-
- return [NSArray arrayWithObjects:a,b,nil];
+ NSString *a = nil;
+ NSString *b = nil;
+ NSScanner *scanner=[NSScanner scannerWithString:line];
+ if([scanner scanString:@"Binary files " intoString:NULL]){
+ [scanner scanUpToString:@" and" intoString:&a];
+ [scanner scanString:@"and" intoString:NULL];
+ [scanner scanUpToString:@" differ" intoString:&b];
+ }
+ if (![a isAbsolutePath]) {
+ a=[a substringFromIndex:2];
+ }
+ if (![b isAbsolutePath]) {
+ b=[b substringFromIndex:2];
+ }
+
+ return [NSArray arrayWithObjects:a,b,nil];
}
+(NSString*)mimeTypeForFileName:(NSString*)name
{
NSString *mimeType = nil;
- NSInteger i=[name rangeOfString:@"." options:NSBackwardsSearch].location;
- if(i!=NSNotFound){
- NSString *ext=[name substringFromIndex:i+1];
- CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)ext, NULL);
- if(UTI){
- CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
- if(registeredType){
- mimeType = NSMakeCollectable(registeredType);
- }
- CFRelease(UTI);
- }
- }
+ NSInteger i=[name rangeOfString:@"." options:NSBackwardsSearch].location;
+ if(i!=NSNotFound){
+ NSString *ext=[name substringFromIndex:i+1];
+ CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)ext, NULL);
+ if(UTI){
+ CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
+ if(registeredType){
+ mimeType = NSMakeCollectable(registeredType);
+ }
+ CFRelease(UTI);
+ }
+ }
return mimeType;
}
+(BOOL)isDiffHeader:(NSString*)line
{
- unichar c=[line characterAtIndex:0];
- return (c=='i') || (c=='m') || (c=='n') || (c=='d') || (c=='-') || (c=='+');
+ unichar c=[line characterAtIndex:0];
+ return (c=='i') || (c=='m') || (c=='n') || (c=='d') || (c=='-') || (c=='+');
}
+(BOOL)isImage:(NSString*)file
{
- NSString *mimeType=[GLFileView mimeTypeForFileName:file];
- return (mimeType!=nil) && ([mimeType rangeOfString:@"image/" options:NSCaseInsensitiveSearch].location!=NSNotFound);
+ NSString *mimeType=[GLFileView mimeTypeForFileName:file];
+ return (mimeType!=nil) && ([mimeType rangeOfString:@"image/" options:NSCaseInsensitiveSearch].location!=NSNotFound);
}
+(BOOL)isBinaryFile:(NSString *)line
{
- return (([line length]>12) && [[line substringToIndex:12] isEqualToString:@"Binary files"]);
+ return (([line length]>12) && [[line substringToIndex:12] isEqualToString:@"Binary files"]);
}
+(BOOL)isStartDiff:(NSString *)line
{
- return (([line length]>10) && [[line substringToIndex:10] isEqualToString:@"diff --git"]);
+ return (([line length]>10) && [[line substringToIndex:10] isEqualToString:@"diff --git"]);
}
+(BOOL)isStartBlock:(NSString *)line
{
- return (([line length]>3) && [[line substringToIndex:3] isEqualToString:@"@@ "]);
+ return (([line length]>3) && [[line substringToIndex:3] isEqualToString:@"@@ "]);
}
- (NSString *) parseBlame:(NSString *)txt
{
- txt=[GLFileView parseHTML:txt];
-
- NSArray *lines = [txt componentsSeparatedByString:@"\n"];
- NSString *line;
- NSMutableDictionary *headers=[NSMutableDictionary dictionary];
- NSMutableString *res=[NSMutableString string];
-
- [res appendString:@"\n"];
- int i=0;
- while(i<[lines count]){
- line=[lines objectAtIndex:i];
- NSArray *header=[line componentsSeparatedByString:@" "];
- if([header count]==4){
- NSString *commitID = (NSString *)[header objectAtIndex:0];
- int nLines=[(NSString *)[header objectAtIndex:3] intValue];
- [res appendFormat:@"\n",nLines];
- line=[lines objectAtIndex:++i];
- if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
- NSString *author=[line stringByReplacingOccurrencesOfString:@"author" withString:@""];
- NSString *summary=nil;
- while(summary==nil){
- line=[lines objectAtIndex:i++];
- if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
- summary=[line stringByReplacingOccurrencesOfString:@"summary" withString:@""];
- }
- }
- NSRange trunc_c={0,7};
- NSString *truncate_c=commitID;
- if([commitID length]>8){
- truncate_c=[commitID substringWithRange:trunc_c];
- }
- NSRange trunc={0,22};
- NSString *truncate_a=author;
- if([author length]>22){
- truncate_a=[author substringWithRange:trunc];
- }
- NSString *truncate_s=summary;
- if([summary length]>30){
- truncate_s=[summary substringWithRange:trunc];
- }
- NSString *block=[NSString stringWithFormat:@"%@ %@ %@ | \n\n",commitID,truncate_c,truncate_a,truncate_s];
- [headers setObject:block forKey:[header objectAtIndex:0]];
- }
- [res appendString:[headers objectForKey:[header objectAtIndex:0]]];
-
- NSMutableString *code=[NSMutableString string];
- do{
- line=[lines objectAtIndex:i++];
- }while([line characterAtIndex:0]!='\t');
- line=[line substringFromIndex:1];
- [code appendString:line];
- [code appendString:@"\n"];
-
- int n;
- for(n=1;n%@",[header objectAtIndex:2],code];
- [res appendString:@" | \n"];
- }else{
- break;
- }
- [res appendString:@"
\n"];
- }
- [res appendString:@"
\n"];
- //NSLog(@"%@",res);
-
- return (NSString *)res;
+ txt=[GLFileView parseHTML:txt];
+
+ NSArray *lines = [txt componentsSeparatedByString:@"\n"];
+ NSString *line;
+ NSMutableDictionary *headers=[NSMutableDictionary dictionary];
+ NSMutableString *res=[NSMutableString string];
+
+ [res appendString:@"\n"];
+ int i=0;
+ while(i<[lines count]){
+ line=[lines objectAtIndex:i];
+ NSArray *header=[line componentsSeparatedByString:@" "];
+ if([header count]==4){
+ NSString *commitID = (NSString *)[header objectAtIndex:0];
+ int nLines=[(NSString *)[header objectAtIndex:3] intValue];
+ [res appendFormat:@"\n",nLines];
+ line=[lines objectAtIndex:++i];
+ if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"author"]){
+ NSString *author=[line stringByReplacingOccurrencesOfString:@"author" withString:@""];
+ NSString *summary=nil;
+ while(summary==nil){
+ line=[lines objectAtIndex:i++];
+ if([[[line componentsSeparatedByString:@" "] objectAtIndex:0] isEqual:@"summary"]){
+ summary=[line stringByReplacingOccurrencesOfString:@"summary" withString:@""];
+ }
+ }
+ NSRange trunc_c={0,7};
+ NSString *truncate_c=commitID;
+ if([commitID length]>8){
+ truncate_c=[commitID substringWithRange:trunc_c];
+ }
+ NSRange trunc={0,22};
+ NSString *truncate_a=author;
+ if([author length]>22){
+ truncate_a=[author substringWithRange:trunc];
+ }
+ NSString *truncate_s=summary;
+ if([summary length]>30){
+ truncate_s=[summary substringWithRange:trunc];
+ }
+ NSString *block=[NSString stringWithFormat:@"%@ %@ %@ | \n\n",commitID,truncate_c,truncate_a,truncate_s];
+ [headers setObject:block forKey:[header objectAtIndex:0]];
+ }
+ [res appendString:[headers objectForKey:[header objectAtIndex:0]]];
+
+ NSMutableString *code=[NSMutableString string];
+ do{
+ line=[lines objectAtIndex:i++];
+ }while([line characterAtIndex:0]!='\t');
+ line=[line substringFromIndex:1];
+ [code appendString:line];
+ [code appendString:@"\n"];
+
+ int n;
+ for(n=1;n%@",[header objectAtIndex:2],code];
+ [res appendString:@" | \n"];
+ }else{
+ break;
+ }
+ [res appendString:@"
\n"];
+ }
+ [res appendString:@"
\n"];
+ //NSLog(@"%@",res);
+
+ return (NSString *)res;
}
@@ -538,38 +589,38 @@
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex
{
- return kFileListSplitViewLeftMin;
+ return kFileListSplitViewLeftMin;
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex
{
- return [splitView frame].size.width - [splitView dividerThickness] - kFileListSplitViewRightMin;
+ return [splitView frame].size.width - [splitView dividerThickness] - kFileListSplitViewRightMin;
}
// while the user resizes the window keep the left (file list) view constant and just resize the right view
// unless the right view gets too small
- (void)splitView:(NSSplitView *)splitView resizeSubviewsWithOldSize:(NSSize)oldSize
{
- NSRect newFrame = [splitView frame];
-
- float dividerThickness = [splitView dividerThickness];
-
- NSView *leftView = [[splitView subviews] objectAtIndex:0];
- NSRect leftFrame = [leftView frame];
- leftFrame.size.height = newFrame.size.height;
-
- if ((newFrame.size.width - leftFrame.size.width - dividerThickness) < kFileListSplitViewRightMin) {
- leftFrame.size.width = newFrame.size.width - kFileListSplitViewRightMin - dividerThickness;
- }
-
- NSView *rightView = [[splitView subviews] objectAtIndex:1];
- NSRect rightFrame = [rightView frame];
- rightFrame.origin.x = leftFrame.size.width + dividerThickness;
- rightFrame.size.width = newFrame.size.width - rightFrame.origin.x;
- rightFrame.size.height = newFrame.size.height;
-
- [leftView setFrame:leftFrame];
- [rightView setFrame:rightFrame];
+ NSRect newFrame = [splitView frame];
+
+ float dividerThickness = [splitView dividerThickness];
+
+ NSView *leftView = [[splitView subviews] objectAtIndex:0];
+ NSRect leftFrame = [leftView frame];
+ leftFrame.size.height = newFrame.size.height;
+
+ if ((newFrame.size.width - leftFrame.size.width - dividerThickness) < kFileListSplitViewRightMin) {
+ leftFrame.size.width = newFrame.size.width - kFileListSplitViewRightMin - dividerThickness;
+ }
+
+ NSView *rightView = [[splitView subviews] objectAtIndex:1];
+ NSRect rightFrame = [rightView frame];
+ rightFrame.origin.x = leftFrame.size.width + dividerThickness;
+ rightFrame.size.width = newFrame.size.width - rightFrame.origin.x;
+ rightFrame.size.height = newFrame.size.height;
+
+ [leftView setFrame:leftFrame];
+ [rightView setFrame:rightFrame];
}
// NSSplitView does not save and restore the position of the SplitView correctly so do it manually
diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m
index 859387e..5c74df5 100644
--- a/PBWebHistoryController.m
+++ b/PBWebHistoryController.m
@@ -116,8 +116,8 @@
NSString *html=[NSString stringWithFormat:@"%@%@%@
",header,fileList,diffs];
- html=[html stringByReplacingOccurrencesOfString:@"{SHA}" withString:[NSString stringWithFormat:@"%@^",[currentSha string]]];
- html=[html stringByReplacingOccurrencesOfString:@"{SHA2}" withString:[currentSha string]];
+ html=[html stringByReplacingOccurrencesOfString:@"{SHA_PREV}" withString:[NSString stringWithFormat:@"%@^",[currentSha string]]];
+ html=[html stringByReplacingOccurrencesOfString:@"{SHA}" withString:[currentSha string]];
[[view windowScriptObject] callWebScriptMethod:@"showCommit" withArguments:[NSArray arrayWithObject:html]];
diff --git a/html/views/diff/diffWindow.css b/html/views/diff/diffWindow.css
index b80b988..932dbc1 100644
--- a/html/views/diff/diffWindow.css
+++ b/html/views/diff/diffWindow.css
@@ -4,6 +4,7 @@ table.diff {
width: 100%;
border-collapse: collapse;
margin-bottom: 10px;
+ -webkit-box-shadow: 5px 5px 5px #ccc;
}
table.diff tr td {
@@ -71,7 +72,6 @@ table.diff .filemerge {
}
#diff table.diff {
- -webkit-box-shadow: 5px 5px 5px #ccc;
width: 98%;
margin: auto auto 20px 1%;
}