@@ -32,12 +32,18 @@ @interface GIFilesTableView : GITableView
32
32
@property (nonatomic , assign ) GIDiffFilesViewController* controller;
33
33
@end
34
34
35
- @interface GIDiffFilesViewController ()
35
+ @interface GIDiffFilesViewController () < NSFilePromiseProviderDelegate >
36
36
@property (nonatomic , weak ) IBOutlet GIFilesTableView* tableView;
37
37
@property (nonatomic , weak ) IBOutlet NSTextField * emptyTextField;
38
38
@property (nonatomic , readonly ) NSArray * items;
39
39
@end
40
40
41
+ // / Allows augmenting a file promise with custom intra-app data.
42
+ API_AVAILABLE (macos(10.12 ))
43
+ @interface GIDiffFileProvider : NSFilePromiseProvider
44
+ @property(strong) id<NSPasteboardWriting> overridePasteboardWriter;
45
+ @end
46
+
41
47
@implementation GIFileCellView
42
48
@end
43
49
@@ -204,6 +210,20 @@ - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView {
204
210
NSURL * url = [NSURL fileURLWithPath: path isDirectory: NO ];
205
211
[pasteboardItem setString: url.absoluteString forType: GIPasteboardTypeFileURL];
206
212
213
+ if (@available (macOS 10.12 , *)) {
214
+ if (GC_FILE_MODE_IS_FILE (delta.oldFile .mode ) || GC_FILE_MODE_IS_FILE (delta.newFile .mode )) {
215
+ NSString * pathExtension = delta.canonicalPath .pathExtension ;
216
+ NSString * utType = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension , (__bridge CFStringRef)pathExtension, kUTTypeData );
217
+
218
+ if (utType) {
219
+ GIDiffFileProvider* provider = [[GIDiffFileProvider alloc ] initWithFileType: utType delegate: self ];
220
+ provider.userInfo = delta;
221
+ provider.overridePasteboardWriter = pasteboardItem;
222
+ return provider;
223
+ }
224
+ }
225
+ }
226
+
207
227
return pasteboardItem;
208
228
}
209
229
@@ -301,4 +321,57 @@ - (void)tableViewSelectionDidChange:(NSNotification*)notification {
301
321
}
302
322
}
303
323
324
+ #pragma mark - NSFilePromiseProviderDelegate
325
+
326
+ - (NSString *)_SHA1ForDelta : (GCDiffDelta*)delta {
327
+ switch (delta.change ) {
328
+ case kGCFileDiffChange_Deleted :
329
+ case kGCFileDiffChange_Unmodified :
330
+ case kGCFileDiffChange_Ignored :
331
+ case kGCFileDiffChange_Untracked :
332
+ case kGCFileDiffChange_Unreadable :
333
+ return delta.oldFile .SHA1 ;
334
+ case kGCFileDiffChange_Added :
335
+ case kGCFileDiffChange_Modified :
336
+ case kGCFileDiffChange_Renamed :
337
+ case kGCFileDiffChange_Copied :
338
+ case kGCFileDiffChange_TypeChanged :
339
+ case kGCFileDiffChange_Conflicted :
340
+ return delta.newFile .SHA1 ;
341
+ }
342
+ }
343
+
344
+ - (NSString *)filePromiseProvider : (NSFilePromiseProvider *)filePromiseProvider fileNameForType : (NSString *)fileType API_AVAILABLE(macos(10.12 )) {
345
+ GCDiffDelta* delta = filePromiseProvider.userInfo ;
346
+ NSString * SHA1 = [[self _SHA1ForDelta: delta] substringToIndex: 7 ];
347
+ NSString * basename = delta.canonicalPath .stringByDeletingPathExtension .lastPathComponent ;
348
+ NSString * pathExtension = delta.canonicalPath .pathExtension ;
349
+ NSString * filename = [[NSString stringWithFormat: @" %@ (%@ )" , basename, SHA1] stringByAppendingPathExtension: pathExtension];
350
+ return filename;
351
+ }
352
+
353
+ - (void )filePromiseProvider : (NSFilePromiseProvider *)filePromiseProvider writePromiseToURL : (NSURL *)url completionHandler : (void (^)(NSError * errorOrNil))completionHandler API_AVAILABLE(macos(10.12 )) {
354
+ GCDiffDelta* delta = filePromiseProvider.userInfo ;
355
+ NSString * SHA1 = [self _SHA1ForDelta: delta];
356
+ NSError * error;
357
+ BOOL success = [delta.diff.repository exportBlobWithSHA1: SHA1 toPath: url.path error: &error];
358
+ completionHandler (success ? nil : error);
359
+ }
360
+
361
+ @end
362
+
363
+ @implementation GIDiffFileProvider
364
+
365
+ - (NSArray <NSPasteboardType>*)writableTypesForPasteboard : (NSPasteboard *)pasteboard {
366
+ return [[self .overridePasteboardWriter writableTypesForPasteboard: pasteboard] arrayByAddingObjectsFromArray: [super writableTypesForPasteboard: pasteboard]];
367
+ }
368
+
369
+ - (NSPasteboardWritingOptions )writingOptionsForType : (NSPasteboardType )type pasteboard : (NSPasteboard *)pasteboard {
370
+ return [self .overridePasteboardWriter writingOptionsForType: type pasteboard: pasteboard] ?: [super writingOptionsForType: type pasteboard: pasteboard];
371
+ }
372
+
373
+ - (id )pasteboardPropertyListForType : (NSPasteboardType )type {
374
+ return [self .overridePasteboardWriter pasteboardPropertyListForType: type] ?: [super pasteboardPropertyListForType: type];
375
+ }
376
+
304
377
@end
0 commit comments