Skip to content
Snippets Groups Projects
Commit a0d37c1f authored by George Nachman's avatar George Nachman
Browse files

Clean things up

parent cc6e0a3e
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -105,6 +105,16 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return YES;
}
 
- (void)dealloc {
[_records release];
[_expandedCache release];
[_managedObjectContext release];
[_tree release];
[super dealloc];
}
#pragma mark - Filesystem
- (NSString *)pathForFileNamed:(NSString *)name {
NSString *path;
path = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,
Loading
Loading
@@ -129,20 +139,14 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
}
 
- (NSString *)databaseFilenamePrefix {
return @"CommandHistory.sqlite";
return @"ShellHistory.sqlite";
}
 
- (NSString *)pathToDatabase {
return [self pathForFileNamed:self.databaseFilenamePrefix];
}
 
- (void)dealloc {
[_records release];
[_expandedCache release];
[_managedObjectContext release];
[_tree release];
[super dealloc];
}
#pragma mark - Core Data
 
// Note: setting vacuum to YES forces it to use the on-disk sqlite database. This allows you to
// vacuum a database after changing the setting to in-memory. It doesn't make sense to vacuum RAM,
Loading
Loading
@@ -218,34 +222,6 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return YES;
}
 
- (void)backingStoreTypeDidChange {
if (!self.saveToDisk) {
[self eraseCommandHistory:YES directories:YES];
}
[_managedObjectContext release];
_managedObjectContext = nil;
[self initializeCoreDataWithRetry:YES vacuum:NO];
// Reload everything.
[_records removeAllObjects];
[_expandedCache removeAllObjects];
[_tree release];
_tree = [[iTermDirectoryTree alloc] init];
[self loadObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
}
- (BOOL)saveToDisk {
return [iTermPreferences boolForKey:kPreferenceKeySavePasteAndCommandHistory];
}
- (BOOL)deleteDatabase {
NSString *path = [[self pathToDatabase] stringByDeletingLastPathComponent];
NSDirectoryEnumerator<NSString *> *enumerator =
Loading
Loading
@@ -266,6 +242,136 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return foundAny && !anyErrors;
}
 
- (void)deleteObjectsWithEntityName:(NSString *)entityName {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:entityName];
NSArray *objects = [_managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *object in objects) {
[_managedObjectContext deleteObject:object];
}
}
- (void)saveObjectGraph {
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to save command history: %@", error);
}
}
- (BOOL)saveToDisk {
return [iTermPreferences boolForKey:kPreferenceKeySavePasteAndCommandHistory];
}
- (NSArray *)managedObjects {
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:[iTermHostRecordMO entityName]];
NSError *error = nil;
return [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
}
- (void)vacuum {
if (_savingToDisk) {
// No sense vacuuming RAM.
// We have to vacuum to erase history in journals.
[_managedObjectContext release];
_managedObjectContext = nil;
[self initializeCoreDataWithRetry:YES vacuum:YES];
// Reinitialize so we can go on with life.
[_managedObjectContext release];
_managedObjectContext = nil;
[self initializeCoreDataWithRetry:YES vacuum:NO];
}
// Reload everything.
[_records removeAllObjects];
[_expandedCache removeAllObjects];
[_tree release];
_tree = [[iTermDirectoryTree alloc] init];
[self loadObjectGraph];
}
#pragma mark - Migration
// Returns YES if a migration was attempted.
- (BOOL)migrateFromPlistToCoreData {
BOOL attempted = NO;
if ([self migrateCommandHistoryFromPlistToCoreData]) {
attempted = YES;
}
if ([self migrateDirectoriesFromPlistToCoreData]) {
attempted = YES;
}
return attempted;
}
- (BOOL)migrateDirectoriesFromPlistToCoreData {
NSString *path = [self pathToDeprecatedDirectoriesPlist];
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]) {
return NO;
}
NSDictionary *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
for (NSString *host in archive) {
NSArray *parts = [host componentsSeparatedByString:@"@"];
if (parts.count != 2) {
continue;
}
iTermHostRecordMO *hostRecord = _records[host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
}
hostRecord.username = parts[0];
hostRecord.hostname = parts[1];
for (NSDictionary *dict in archive[host]) {
iTermRecentDirectoryMO *directory =
[iTermRecentDirectoryMO entryWithDictionary:dict
inContext:_managedObjectContext];
[hostRecord addDirectoriesObject:directory];
directory.remoteHost = hostRecord;
}
}
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to migrate directory history: %@", error);
} else {
[[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
}
return YES;
}
- (BOOL)migrateCommandHistoryFromPlistToCoreData {
NSString *path = [self pathToDeprecatedCommandHistoryPlist];
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]) {
return NO;
}
NSDictionary *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:self.pathToDeprecatedCommandHistoryPlist];
for (NSString *host in archive) {
NSArray *parts = [host componentsSeparatedByString:@"@"];
if (parts.count != 2) {
continue;
}
iTermHostRecordMO *hostRecord = _records[host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
}
hostRecord.username = parts[0];
hostRecord.hostname = parts[1];
for (NSDictionary *commandDict in archive[host]) {
iTermCommandHistoryEntryMO *managedObject =
[iTermCommandHistoryEntryMO commandHistoryEntryFromDeprecatedDictionary:commandDict
inContext:_managedObjectContext];
managedObject.remoteHost = hostRecord;
[hostRecord addEntriesObject:managedObject];
}
}
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to migrate command history: %@", error);
} else {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedCommandHistoryPlist error:NULL];
}
return YES;
}
#pragma mark - APIs
 
+ (void)showInformationalMessage {
Loading
Loading
@@ -295,61 +401,71 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
}
}
 
- (BOOL)commandHistoryHasEverBeenUsed {
return (_records.count > 0 ||
[[NSUserDefaults standardUserDefaults] boolForKey:kCommandHistoryHasEverBeenUsed]);
}
- (iTermRecentDirectoryMO *)recordUseOfPath:(NSString *)path
onHost:(VT100RemoteHost *)host
isChange:(BOOL)isChange {
if (!isChange || !path) {
return nil;
- (void)backingStoreTypeDidChange {
if (!self.saveToDisk) {
[self eraseCommandHistory:YES directories:YES];
}
 
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
hostRecord.hostname = host.hostname;
hostRecord.username = host.username;
[self setRecord:hostRecord forHost:host];
[_managedObjectContext release];
_managedObjectContext = nil;
[self initializeCoreDataWithRetry:YES vacuum:NO];
// Reload everything.
[_records removeAllObjects];
[_expandedCache removeAllObjects];
[_tree release];
_tree = [[iTermDirectoryTree alloc] init];
[self loadObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
}
 
// Check if we already have it;
iTermRecentDirectoryMO *directory = nil;
for (iTermRecentDirectoryMO *existingDirectory in hostRecord.directories) {
if ([existingDirectory.path isEqualToString:path]) {
directory = existingDirectory;
break;
}
- (void)eraseCommandHistory:(BOOL)commandHistory directories:(BOOL)directories {
// This operates at a low level to ensure data is really removed.
if (commandHistory) {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedCommandHistoryPlist
error:NULL];
}
if (directories) {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedDirectoriesPlist
error:NULL];
}
 
if (!directory) {
// Is a new directory on this host.
directory = [NSEntityDescription insertNewObjectForEntityForName:[iTermRecentDirectoryMO entityName]
inManagedObjectContext:_managedObjectContext];
directory.path = path;
[_tree addPath:path];
[hostRecord addDirectoriesObject:directory];
if (commandHistory) {
[self deleteObjectsWithEntityName:[iTermCommandHistoryEntryMO entityName]];
[self deleteObjectsWithEntityName:[iTermCommandHistoryCommandUseMO entityName]];
}
if (directories) {
[self deleteObjectsWithEntityName:[iTermRecentDirectoryMO entityName]];
}
if (commandHistory && directories) {
[self deleteObjectsWithEntityName:[iTermHostRecordMO entityName]];
}
directory.useCount = @(directory.useCount.integerValue + 1);
directory.lastUse = @([self now]);
 
[self saveDirectories];
[self saveObjectGraph];
[self vacuum];
 
return directory;
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
 
- (NSArray *)directoriesSortedByScoreOnHost:(VT100RemoteHost *)host {
return [[self directoriesForHost:host] sortedArrayUsingSelector:@selector(compare:)];
}
#pragma mark - Command History
#pragma mark Mutation
 
- (void)addCommand:(NSString *)command
onHost:(VT100RemoteHost *)host
inDirectory:(NSString *)directory
withMark:(VT100ScreenMark *)mark {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kCommandHistoryHasEverBeenUsed];
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
Loading
Loading
@@ -357,7 +473,7 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
hostRecord.username = host.username;
[self setRecord:hostRecord forHost:host];
}
iTermCommandHistoryEntryMO *theEntry = nil;
for (iTermCommandHistoryEntryMO *entry in hostRecord.entries) {
if ([entry.command isEqualToString:command]) {
Loading
Loading
@@ -365,7 +481,7 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
break;
}
}
if (!theEntry) {
theEntry = [iTermCommandHistoryEntryMO commandHistoryEntryInContext:_managedObjectContext];
theEntry.command = command;
Loading
Loading
@@ -376,13 +492,13 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
theEntry.timeOfLastUse = @([self now]);
iTermCommandHistoryCommandUseMO *commandUse =
[iTermCommandHistoryCommandUseMO commandHistoryCommandUseInContext:_managedObjectContext];
[iTermCommandHistoryCommandUseMO commandHistoryCommandUseInContext:_managedObjectContext];
commandUse.time = theEntry.timeOfLastUse;
commandUse.mark = mark;
commandUse.directory = directory;
commandUse.command = theEntry.command;
[theEntry addUsesObject:commandUse];
NSString *key = host.key ?: @"";
if (_expandedCache[key]) {
[_expandedCache[key] addObject:commandUse];
Loading
Loading
@@ -390,38 +506,6 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
[self saveCommandHistory];
}
 
- (NSTimeInterval)now {
return [NSDate timeIntervalSinceReferenceDate];
}
- (void)saveObjectGraph {
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to save command history: %@", error);
}
}
- (void)saveCommandHistory {
[self saveObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
}
- (void)saveDirectories {
[self saveObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
}
}
- (void)setDirectory:(iTermRecentDirectoryMO *)directory starred:(BOOL)starred {
directory.starred = @(starred);
[self saveDirectories];
}
- (void)setStatusOfCommandAtMark:(VT100ScreenMark *)mark
onHost:(VT100RemoteHost *)remoteHost
to:(int)status {
Loading
Loading
@@ -435,27 +519,11 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
}
}
 
- (BOOL)haveCommandsForHost:(VT100RemoteHost *)host {
return [[[self recordForHost:host] entries] count] > 0;
}
- (BOOL)haveDirectoriesForHost:(VT100RemoteHost *)host {
return [[[self recordForHost:host] directories] count] > 0;
}
#pragma mark Lookup
 
- (NSArray<iTermCommandHistoryCommandUseMO *> *)autocompleteSuggestionsWithPartialCommand:(NSString *)partialCommand
onHost:(VT100RemoteHost *)host {
NSArray<iTermCommandHistoryEntryMO *> *temp =
[self commandHistoryEntriesWithPrefix:partialCommand onHost:host];
NSMutableArray<iTermCommandHistoryCommandUseMO *> *result = [NSMutableArray array];
for (iTermCommandHistoryEntryMO *entry in temp) {
iTermCommandHistoryCommandUseMO *lastUse = [entry.uses lastObject];
if (lastUse) {
[result addObject:lastUse];
}
}
return result;
- (BOOL)commandHistoryHasEverBeenUsed {
return (_records.count > 0 ||
[[NSUserDefaults standardUserDefaults] boolForKey:kCommandHistoryHasEverBeenUsed]);
}
 
- (NSArray<iTermCommandHistoryEntryMO *> *)commandHistoryEntriesWithPrefix:(NSString *)partialCommand
Loading
Loading
@@ -478,25 +546,41 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return [sortedEntries subarrayWithRange:NSMakeRange(0, MIN(kMaxResults, sortedEntries.count))];
}
 
- (NSMutableArray<iTermCommandHistoryCommandUseMO *> *)commandUsesByExpandingEntries:(NSArray<iTermCommandHistoryEntryMO *> *)array {
- (NSArray<iTermCommandHistoryCommandUseMO *> *)autocompleteSuggestionsWithPartialCommand:(NSString *)partialCommand
onHost:(VT100RemoteHost *)host {
NSArray<iTermCommandHistoryEntryMO *> *temp =
[self commandHistoryEntriesWithPrefix:partialCommand onHost:host];
NSMutableArray<iTermCommandHistoryCommandUseMO *> *result = [NSMutableArray array];
for (iTermCommandHistoryEntryMO *entry in array) {
for (iTermCommandHistoryCommandUseMO *commandUse in entry.uses) {
if (!commandUse.command) {
commandUse.command = entry.command;
}
[result addObject:commandUse];
for (iTermCommandHistoryEntryMO *entry in temp) {
iTermCommandHistoryCommandUseMO *lastUse = [entry.uses lastObject];
if (lastUse) {
[result addObject:lastUse];
}
}
// Sort result chronologically from earliest to latest
[result sortWithOptions:0 usingComparator:^NSComparisonResult(iTermCommandHistoryCommandUseMO *obj1,
iTermCommandHistoryCommandUseMO *obj2) {
return [(obj1.time ?: @0) compare:(obj2.time ?: @0)];
}];
return result;
}
 
- (BOOL)haveCommandsForHost:(VT100RemoteHost *)host {
return [[[self recordForHost:host] entries] count] > 0;
}
- (iTermCommandHistoryCommandUseMO *)commandUseWithMarkGuid:(NSString *)markGuid
onHost:(VT100RemoteHost *)host {
if (!markGuid) {
return nil;
}
iTermHostRecordMO *hostRecord = [self recordForHost:host];
// TODO: Create an index of markGuid's in command uses if this becomes a performance problem during restore.
for (iTermCommandHistoryEntryMO *entry in hostRecord.entries) {
for (iTermCommandHistoryCommandUseMO *use in entry.uses) {
if ([use.markGuid isEqual:markGuid]) {
return use;
}
}
}
return nil;
}
- (NSArray<iTermCommandHistoryCommandUseMO *> *)commandUsesForHost:(VT100RemoteHost *)host {
NSString *key = host.key ?: @"";
if (!_expandedCache[key]) {
Loading
Loading
@@ -505,27 +589,95 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return _expandedCache[key];
}
 
#pragma mark - Private
#pragma mark - Recent Directories
 
- (void)loadExpandedCacheForHost:(VT100RemoteHost *)host {
NSString *key = host.key ?: @"";
#pragma mark Mutation
 
NSArray<iTermCommandHistoryEntryMO *> *temp =
[self commandHistoryEntriesWithPrefix:@"" onHost:host];
NSMutableArray<iTermCommandHistoryCommandUseMO *> *expanded =
[self commandUsesByExpandingEntries:temp];
- (iTermRecentDirectoryMO *)recordUseOfPath:(NSString *)path
onHost:(VT100RemoteHost *)host
isChange:(BOOL)isChange {
if (!isChange || !path) {
return nil;
}
 
_expandedCache[key] = expanded;
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
hostRecord.hostname = host.hostname;
hostRecord.username = host.username;
[self setRecord:hostRecord forHost:host];
}
 
// Check if we already have it;
iTermRecentDirectoryMO *directory = nil;
for (iTermRecentDirectoryMO *existingDirectory in hostRecord.directories) {
if ([existingDirectory.path isEqualToString:path]) {
directory = existingDirectory;
break;
}
}
if (!directory) {
// Is a new directory on this host.
directory = [NSEntityDescription insertNewObjectForEntityForName:[iTermRecentDirectoryMO entityName]
inManagedObjectContext:_managedObjectContext];
directory.path = path;
[_tree addPath:path];
[hostRecord addDirectoriesObject:directory];
}
directory.useCount = @(directory.useCount.integerValue + 1);
directory.lastUse = @([self now]);
[self saveDirectories];
return directory;
}
 
- (NSArray *)managedObjects {
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:[iTermHostRecordMO entityName]];
NSError *error = nil;
return [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
- (void)setDirectory:(iTermRecentDirectoryMO *)directory starred:(BOOL)starred {
directory.starred = @(starred);
[self saveDirectories];
}
#pragma mark Lookup
- (NSIndexSet *)abbreviationSafeIndexesInRecentDirectory:(iTermRecentDirectoryMO *)entry {
return [_tree abbreviationSafeIndexesInPath:entry.path];
}
- (NSArray *)directoriesSortedByScoreOnHost:(VT100RemoteHost *)host {
return [[self directoriesForHost:host] sortedArrayUsingSelector:@selector(compare:)];
}
- (BOOL)haveDirectoriesForHost:(VT100RemoteHost *)host {
return [[[self recordForHost:host] directories] count] > 0;
}
 
#pragma mark - Testing
- (void)eraseCommandHistoryForHost:(VT100RemoteHost *)host {
NSString *key = host.key ?: @"";
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (hostRecord) {
[hostRecord removeEntries:hostRecord.entries];
[_expandedCache removeObjectForKey:key];
[self saveCommandHistory];
}
}
- (void)eraseDirectoriesForHost:(VT100RemoteHost *)host {
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (hostRecord) {
[hostRecord removeDirectories:hostRecord.directories];
[self saveDirectories];
}
}
- (NSTimeInterval)now {
return [NSDate timeIntervalSinceReferenceDate];
}
#pragma mark - Private
- (BOOL)removeOldData {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[NSEntityDescription entityForName:[iTermCommandHistoryCommandUseMO entityName]
Loading
Loading
@@ -578,162 +730,56 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
}
}
 
// Returns YES if a migration was attempted.
- (BOOL)migrateFromPlistToCoreData {
BOOL attempted = NO;
if ([self migrateCommandHistoryFromPlistToCoreData]) {
attempted = YES;
}
if ([self migrateDirectoriesFromPlistToCoreData]) {
attempted = YES;
}
return attempted;
}
- (BOOL)migrateDirectoriesFromPlistToCoreData {
NSString *path = [self pathToDeprecatedDirectoriesPlist];
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]) {
return NO;
}
NSDictionary *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
for (NSString *host in archive) {
NSArray *parts = [host componentsSeparatedByString:@"@"];
if (parts.count != 2) {
continue;
}
iTermHostRecordMO *hostRecord = _records[host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
}
hostRecord.username = parts[0];
hostRecord.hostname = parts[1];
for (NSDictionary *dict in archive[host]) {
iTermRecentDirectoryMO *directory =
[iTermRecentDirectoryMO entryWithDictionary:dict
inContext:_managedObjectContext];
[hostRecord addDirectoriesObject:directory];
directory.remoteHost = hostRecord;
}
}
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to migrate directory history: %@", error);
} else {
[[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
}
return YES;
- (iTermHostRecordMO *)recordForHost:(VT100RemoteHost *)host {
return _records[host.key ?: @""];
}
 
- (BOOL)migrateCommandHistoryFromPlistToCoreData {
NSString *path = [self pathToDeprecatedCommandHistoryPlist];
if (![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]) {
return NO;
}
NSDictionary *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:self.pathToDeprecatedCommandHistoryPlist];
for (NSString *host in archive) {
NSArray *parts = [host componentsSeparatedByString:@"@"];
if (parts.count != 2) {
continue;
}
iTermHostRecordMO *hostRecord = _records[host];
if (!hostRecord) {
hostRecord = [iTermHostRecordMO hostRecordInContext:_managedObjectContext];
}
hostRecord.username = parts[0];
hostRecord.hostname = parts[1];
for (NSDictionary *commandDict in archive[host]) {
iTermCommandHistoryEntryMO *managedObject =
[iTermCommandHistoryEntryMO commandHistoryEntryFromDeprecatedDictionary:commandDict
inContext:_managedObjectContext];
managedObject.remoteHost = hostRecord;
[hostRecord addEntriesObject:managedObject];
}
}
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(@"Failed to migrate command history: %@", error);
} else {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedCommandHistoryPlist error:NULL];
}
return YES;
- (void)setRecord:(iTermHostRecordMO *)record forHost:(VT100RemoteHost *)host {
_records[host.key ?: @""] = record;
}
 
- (void)vacuum {
if (_savingToDisk) {
// No sense vacuuming RAM.
// We have to vacuum to erase history in journals.
[_managedObjectContext release];
_managedObjectContext = nil;
[self initializeCoreDataWithRetry:YES vacuum:YES];
[_managedObjectContext release];
_managedObjectContext = nil;
#pragma mark Private Command History
 
// Reinitialize so we can go on with life.
[self initializeCoreDataWithRetry:YES vacuum:NO];
- (NSMutableArray<iTermCommandHistoryCommandUseMO *> *)commandUsesByExpandingEntries:(NSArray<iTermCommandHistoryEntryMO *> *)array {
NSMutableArray<iTermCommandHistoryCommandUseMO *> *result = [NSMutableArray array];
for (iTermCommandHistoryEntryMO *entry in array) {
for (iTermCommandHistoryCommandUseMO *commandUse in entry.uses) {
if (!commandUse.command) {
commandUse.command = entry.command;
}
[result addObject:commandUse];
}
}
 
// Reload everything.
[_records removeAllObjects];
[_expandedCache removeAllObjects];
[_tree release];
_tree = [[iTermDirectoryTree alloc] init];
[self loadObjectGraph];
// Sort result chronologically from earliest to latest
[result sortWithOptions:0 usingComparator:^NSComparisonResult(iTermCommandHistoryCommandUseMO *obj1,
iTermCommandHistoryCommandUseMO *obj2) {
return [(obj1.time ?: @0) compare:(obj2.time ?: @0)];
}];
return result;
}
 
- (void)eraseCommandHistory:(BOOL)commandHistory directories:(BOOL)directories {
if (commandHistory) {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedCommandHistoryPlist
error:NULL];
}
if (directories) {
[[NSFileManager defaultManager] removeItemAtPath:self.pathToDeprecatedDirectoriesPlist
error:NULL];
}
- (void)loadExpandedCacheForHost:(VT100RemoteHost *)host {
NSString *key = host.key ?: @"";
 
for (iTermHostRecordMO *hostRecord in _records.allValues) {
if (commandHistory) {
[hostRecord removeEntries:hostRecord.entries];
}
if (directories) {
[hostRecord removeDirectories:hostRecord.directories];
}
}
NSArray<iTermCommandHistoryEntryMO *> *temp =
[self commandHistoryEntriesWithPrefix:@"" onHost:host];
NSMutableArray<iTermCommandHistoryCommandUseMO *> *expanded =
[self commandUsesByExpandingEntries:temp];
 
if (commandHistory) {
[self saveCommandHistory];
}
if (directories) {
[self saveDirectories];
}
_expandedCache[key] = expanded;
 
[self vacuum];
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
 
- (void)eraseCommandHistoryForHost:(VT100RemoteHost *)host {
NSString *key = host.key ?: @"";
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (hostRecord) {
[hostRecord removeEntries:hostRecord.entries];
[_expandedCache removeObjectForKey:key];
[self saveCommandHistory];
}
}
- (void)eraseDirectoriesForHost:(VT100RemoteHost *)host {
iTermHostRecordMO *hostRecord = [self recordForHost:host];
if (hostRecord) {
[hostRecord removeDirectories:hostRecord.directories];
[self saveDirectories];
- (void)saveCommandHistory {
[self saveObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kCommandHistoryDidChangeNotificationName
object:nil];
}
}
 
- (NSIndexSet *)abbreviationSafeIndexesInRecentDirectory:(iTermRecentDirectoryMO *)entry {
return [_tree abbreviationSafeIndexesInPath:entry.path];
}
#pragma mark Private Directories
 
- (NSArray<iTermRecentDirectoryMO *> *)directoriesForHost:(VT100RemoteHost *)host {
NSMutableArray<iTermRecentDirectoryMO *> *results = [NSMutableArray array];
Loading
Loading
@@ -748,29 +794,12 @@ static const NSTimeInterval kMaxTimeToRememberDirectories = 60 * 60 * 24 * 90;
return [starred arrayByAddingObjectsFromArray:results];
}
 
- (iTermCommandHistoryCommandUseMO *)commandUseWithMarkGuid:(NSString *)markGuid
onHost:(VT100RemoteHost *)host {
if (!markGuid) {
return nil;
}
iTermHostRecordMO *hostRecord = [self recordForHost:host];
// TODO: Create an index of markGuid's in command uses if this becomes a performance problem during restore.
for (iTermCommandHistoryEntryMO *entry in hostRecord.entries) {
for (iTermCommandHistoryCommandUseMO *use in entry.uses) {
if ([use.markGuid isEqual:markGuid]) {
return use;
}
}
- (void)saveDirectories {
[self saveObjectGraph];
if (!_initializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:kDirectoriesDidChangeNotificationName
object:nil];
}
return nil;
}
- (iTermHostRecordMO *)recordForHost:(VT100RemoteHost *)host {
return _records[host.key ?: @""];
}
- (void)setRecord:(iTermHostRecordMO *)record forHost:(VT100RemoteHost *)host {
_records[host.key ?: @""] = record;
}
 
@end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment