diff --git a/sources/PTYSession.m b/sources/PTYSession.m index ad482f709f..1e60c67174 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -3872,6 +3872,19 @@ - (NSString *)badgeFormat { } - (void)updateBadgeLabel { + NSMutableArray *badRefs = [NSMutableArray array]; + for (iTermVariableReference *ref in _badgeSwiftyString.refs) { + if ([self.variablesScope variableNamed:iTermVariableKeySessionBadge isReferencedBy:ref]) { + [badRefs addObject:ref]; + } + } + if (badRefs.count) { + for (iTermVariableReference *ref in badRefs) { + [ref removeAllLinks]; + } + [self setSessionSpecificProfileValues:@{ KEY_BADGE_FORMAT: @"[CYCLE DETECTED]" }]; + return; + } [self updateBadgeLabel:[self badgeLabel]]; } diff --git a/sources/iTermSwiftyString.h b/sources/iTermSwiftyString.h index 5e1a5df2b3..fca187804d 100644 --- a/sources/iTermSwiftyString.h +++ b/sources/iTermSwiftyString.h @@ -9,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN +@class iTermVariableReference; @class iTermVariableScope; // Represents a string with interpolated components like: @@ -25,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly, copy) id (^source)(NSString *); @property (nonatomic, readonly, copy) void (^observer)(NSString *); @property (nullable, nonatomic, readonly) NSString *evaluatedString; +@property (nonatomic, readonly) NSArray *refs; // Variables the string depends on @property (nonatomic, readonly) NSSet *dependencies; diff --git a/sources/iTermSwiftyString.m b/sources/iTermSwiftyString.m index 636d68dddb..46d476a390 100644 --- a/sources/iTermSwiftyString.m +++ b/sources/iTermSwiftyString.m @@ -25,7 +25,6 @@ @interface iTermSwiftyString() @implementation iTermSwiftyString { NSMutableSet *_missingFunctions; iTermVariableScope *_scope; - NSArray *_refs; BOOL _observing; } diff --git a/sources/iTermVariables.h b/sources/iTermVariables.h index 59b01054f0..3ee92f0cf6 100644 --- a/sources/iTermVariables.h +++ b/sources/iTermVariables.h @@ -119,6 +119,7 @@ typedef NS_OPTIONS(NSUInteger, iTermVariablesSuggestionContext) { - (void)setValue:(nullable id)value forKey:(NSString *)key NS_UNAVAILABLE; - (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues NS_UNAVAILABLE; - (void)addLinksToReference:(iTermVariableReference *)reference; +- (BOOL)variableNamed:(NSString *)name isReferencedBy:(iTermVariableReference *)reference; @end diff --git a/sources/iTermVariables.m b/sources/iTermVariables.m index 9170540617..f6e5d198cc 100644 --- a/sources/iTermVariables.m +++ b/sources/iTermVariables.m @@ -324,6 +324,20 @@ - (void)addLinkToReference:(iTermVariableReference *)reference } } +- (BOOL)hasLinkToReference:(iTermVariableReference *)reference + path:(NSString *)path { + NSArray *parts = [path componentsSeparatedByString:@"."]; + id value = _values[parts.firstObject]; + if (!value) { + return NO; + } + iTermVariables *sub = [iTermVariables castFrom:value]; + if (sub && parts.count > 1) { + return [sub hasLinkToReference:reference path:[[parts subarrayFromIndex:1] componentsJoinedByString:@"."]]; + } + return [_resolvedLinks[path].allObjects containsObject:reference]; +} + - (void)removeLinkToReference:(iTermVariableReference *)reference path:(NSString *)path { [self removeWeakReferenceFromLinkTable:_resolvedLinks toObject:reference forKey:path]; @@ -659,6 +673,15 @@ - (iTermVariables *)ownerForKey:(NSString *)key stripped:(out NSString **)stripp return owner; } +- (BOOL)variableNamed:(NSString *)name isReferencedBy:(iTermVariableReference *)reference { + NSString *tail; + iTermVariables *variables = [self ownerForKey:name stripped:&tail]; + if (!variables) { + return NO; + } + return [variables hasLinkToReference:reference path:tail]; +} + - (BOOL)setValuesFromDictionary:(NSDictionary *)dict { // Transform dict from {name: object} to {owner: {stripped_name: object}} NSMutableDictionary *> *valuesByOwner = [NSMutableDictionary dictionary];