mirror of
https://github.com/textmate/textmate.git
synced 2026-04-28 03:00:34 -04:00
Let FSItem create finderTags when requested
This does mean that we are taxing our main thread with disk access. This is mainly a problem for users who are using network mounted file systems, but it does provide better abstraction in the code, and should this turn out to be a performance issue, I think a better approach is to fetch the tags in a dispatch queue (initiated by FSItem), and then use KVC to update the property once the tags have been loaded, although ideally such system would use some sort of batching, so that we do not dispatch in each property accessor. Could also have the background directory scanner set a boolean property to indicate if the item has tags, as most items do not, and in that case, we can bypass the disk access. But this then only does half the job of encapsulating how tags are stored.
This commit is contained in:
@@ -12,6 +12,7 @@ PUBLIC @interface OakFinderTag : NSObject
|
||||
@end
|
||||
|
||||
PUBLIC @interface OakFinderTagManager : NSObject
|
||||
+ (NSArray<OakFinderTag*>*)finderTagsForURL:(NSURL*)aURL;
|
||||
+ (NSArray<OakFinderTag*>*)finderTagsFromData:(NSData*)data;
|
||||
+ (NSColor*)backgroundColorForLabel:(NSUInteger)label;
|
||||
+ (NSColor*)foregroundColorForLabel:(NSUInteger)label;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import "OakFinderTag.h"
|
||||
#import <OakFoundation/OakFoundation.h>
|
||||
#import <OakAppKit/NSColor Additions.h>
|
||||
#import <io/path.h>
|
||||
|
||||
@implementation OakFinderTag
|
||||
- (instancetype)initWithDisplayName:(NSString*)name label:(NSUInteger)label markedFavorite:(BOOL)markedFavorite
|
||||
@@ -43,6 +44,20 @@ static struct label_colors_t { NSString* name; NSString* backgroundColor; NSStri
|
||||
};
|
||||
|
||||
@implementation OakFinderTagManager
|
||||
+ (NSArray<OakFinderTag*>*)finderTagsForURL:(NSURL*)aURL
|
||||
{
|
||||
if(aURL.filePathURL)
|
||||
{
|
||||
std::string const bplist = path::get_attr(aURL.fileSystemRepresentation, "com.apple.metadata:_kMDItemUserTags");
|
||||
if(bplist != NULL_STR)
|
||||
{
|
||||
NSData* data = [NSData dataWithBytes:(void*)bplist.data() length:bplist.size()];
|
||||
return [self finderTagsFromData:data];
|
||||
}
|
||||
}
|
||||
return @[ ];
|
||||
}
|
||||
|
||||
+ (NSArray<OakFinderTag*>*)finderTagsFromData:(NSData*)data
|
||||
{
|
||||
id plist = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListImmutable format:nil errorDescription:nil];
|
||||
|
||||
@@ -105,8 +105,6 @@ struct tracking_t : fs::event_callback_t
|
||||
{
|
||||
fs_item_t (dev_t device, dirent const* entry, std::string const& path) : device(device), inode(entry->d_fileno), path(path), target(NULL_STR), is_directory(false), is_link(false), treat_as_directory(false), sort_as_directory(false)
|
||||
{
|
||||
tag_data = path::tag_data(path);
|
||||
|
||||
if(entry->d_type == DT_LNK)
|
||||
{
|
||||
std::string const resolved = path::resolve_head(path);
|
||||
@@ -139,7 +137,6 @@ struct tracking_t : fs::event_callback_t
|
||||
ino_t inode;
|
||||
std::string path;
|
||||
std::string target;
|
||||
std::string tag_data;
|
||||
bool is_directory;
|
||||
bool is_link;
|
||||
bool treat_as_directory;
|
||||
@@ -255,9 +252,6 @@ struct tracking_t : fs::event_callback_t
|
||||
if(allowExpandingLinks && fsItem.is_link && fsItem.sort_as_directory && item.leaf)
|
||||
item.leaf = NO;
|
||||
|
||||
if(fsItem.tag_data != NULL_STR)
|
||||
item.finderTags = [OakFinderTagManager finderTagsFromData:[NSData dataWithBytes:(void*)fsItem.tag_data.data() length:fsItem.tag_data.size()]];
|
||||
|
||||
[array addObject:item];
|
||||
pathsOnDisk.insert(fsItem.path);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#import <OakFoundation/NSString Additions.h>
|
||||
#import <OakAppKit/OakFileIconImage.h>
|
||||
#import <OakAppKit/OakFileManager.h>
|
||||
#import <OakAppKit/OakFinderTag.h>
|
||||
#import <OakAppKit/IOAlertPanel.h>
|
||||
#import <ns/ns.h>
|
||||
#import <io/path.h>
|
||||
@@ -65,6 +66,13 @@ static ino_t inode (std::string const& path)
|
||||
return [self.url path];
|
||||
}
|
||||
|
||||
- (NSArray<OakFinderTag*>*)finderTags
|
||||
{
|
||||
if(!_finderTags)
|
||||
_finderTags = [OakFinderTagManager finderTagsForURL:self.url];
|
||||
return _finderTags;
|
||||
}
|
||||
|
||||
- (scm::status::type)scmStatus
|
||||
{
|
||||
return [_icon isKindOfClass:[OakFileIconImage class]] ? ((OakFileIconImage*)_icon).scmStatus : scm::status::unknown;
|
||||
|
||||
@@ -48,10 +48,6 @@ static NSArray* convert (std::map<std::string, scm::status::type> const& pathsMa
|
||||
item.scmStatus = hideSCMBadge ? scm::status::none : pair.second;
|
||||
item.missing = pair.second == scm::status::deleted;
|
||||
|
||||
std::string const tag_data = path::tag_data(pair.first);
|
||||
if(tag_data != NULL_STR)
|
||||
item.finderTags = [OakFinderTagManager finderTagsFromData:[NSData dataWithBytes:(void*)tag_data.data() length:tag_data.size()]];
|
||||
|
||||
[res addObject:item];
|
||||
}
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user