Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
474 changes: 474 additions & 0 deletions ModernTests/VT100ScreenTests.swift

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions sources/VT100ScreenMutableState+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ iTermTriggerScopeProvider> {
iTermKittyImageController *_kittyImageController;
// When YES, terminal input is collected into printBuffer for ANSI print commands.
BOOL _collectInputForPrinting;
// Precomputed fast-path eligibility. Recomputed at each state-mutation point.
// Access on mutation queue only
BOOL _fastPathEligible;
}

@property (atomic) BOOL hadCommand;
Expand All @@ -67,6 +70,9 @@ iTermTriggerScopeProvider> {
@property (class, atomic, readwrite) BOOL performingJoinedBlock;
@property (nonatomic) BOOL allowNextReport;

- (BOOL)_computeFastPathEligible;
- (void)_recomputeFastPathEligible;

- (iTermEventuallyConsistentIntervalTree *)mutableIntervalTree;
- (iTermEventuallyConsistentIntervalTree *)mutableSavedIntervalTree;
- (iTermColorMap *)mutableColorMap;
Expand Down
2 changes: 1 addition & 1 deletion sources/VT100ScreenMutableState+Resizing.m
Original file line number Diff line number Diff line change
Expand Up @@ -1371,7 +1371,7 @@ - (void)reallySetSize:(VT100GridSize)newSize
newTop:newTop
delegate:delegate];
[altScreenLineBuffer endResizing];
self.commandStartCoord = [self startCoordOfCurrentCommand];
[self setCommandStartCoordWithoutSideEffects:[self startCoordOfCurrentCommand]];
[self sanityCheckIntervalsFrom:oldSize note:@"post-hoc"];
DLog(@"After:\n%@", [self.currentGrid compactLineDumpWithContinuationMarks]);
DLog(@"Cursor at %d,%d", self.currentGrid.cursorX, self.currentGrid.cursorY);
Expand Down
32 changes: 22 additions & 10 deletions sources/VT100ScreenMutableState+TerminalDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -232,17 +232,19 @@ - (VT100ScreenMutableStateAppendInfo)appendInfoForTokens:(NSArray<VT100Token *>
}

- (void)terminalAppendMixedAsciiGang:(NSArray<VT100Token *> *)tokens {
VT100Terminal *terminal = self.terminal;
BOOL canTakeFastPath = (!_collectInputForPrinting &&
![self shouldEvaluateTriggers] &&
![self shouldConvertCharactersToGraphicsCharacterSetInTerminal:terminal] &&
!self.config.publishing &&
self.commandStartCoord.x == -1 &&
// Self-healing recompute: catch staleness from lazy expiry of expectations
// (deadlines pass without notification). Only runs on the slow path so
// the fast path stays a single ivar read.
if (!_fastPathEligible) {
[self _recomputeFastPathEligible];
}
#if DEBUG
ITAssertWithMessage(_fastPathEligible == [self _computeFastPathEligible],
@"Stale _fastPathEligible: cached=%d computed=%d",
_fastPathEligible, [self _computeFastPathEligible]);
#endif
BOOL canTakeFastPath = (_fastPathEligible &&
tokens.count > 0 &&
self.wraparoundMode &&
!self.ansi &&
!self.insert &&
self.currentGrid == self.primaryGrid &&
self.currentGrid.canTakeFastPath);
if (!canTakeFastPath) {
const int numLines = [self appendGangSlowPath:tokens];
Expand Down Expand Up @@ -840,6 +842,7 @@ - (void)terminalPrintBuffer {
DLog(@"string is: %@", string);
self.printBuffer = nil;
_collectInputForPrinting = NO;
[self _recomputeFastPathEligible];
// Pause so that attributes like colors don't change until printing (which is async) can begin.
[self addPausedSideEffect:^(id<VT100ScreenDelegate> delegate, iTermTokenExecutorUnpauser *unpauser) {
DLog(@"begin side-effect");
Expand All @@ -855,6 +858,7 @@ - (void)terminalPrintScreen {
// Print out the whole screen
self.printBuffer = nil;
_collectInputForPrinting = NO;
[self _recomputeFastPathEligible];

// Pause so we print the current state and not future updates.
[self addPausedSideEffect:^(id<VT100ScreenDelegate> delegate, iTermTokenExecutorUnpauser *unpauser) {
Expand All @@ -874,6 +878,7 @@ - (void)terminalBeginRedirectingToPrintBuffer {
// allocate a string for the stuff to be printed
self.printBuffer = [[NSMutableString alloc] init];
_collectInputForPrinting = YES;
[self _recomputeFastPathEligible];
}

- (void)terminalSetWindowTitle:(NSString *)title {
Expand Down Expand Up @@ -2106,16 +2111,23 @@ - (void)terminalSetShellIntegrationVersion:(NSString *)version {
- (void)terminalWraparoundModeDidChangeTo:(BOOL)newValue {
DLog(@"begin %@", @(newValue));
self.wraparoundMode = newValue;
[self _recomputeFastPathEligible];
}

- (void)terminalTypeDidChange {
DLog(@"begin");
self.ansi = [self.terminal isAnsi];
[self _recomputeFastPathEligible];
}

- (void)terminalInsertModeDidChangeTo:(BOOL)newValue {
DLog(@"begin %@", @(newValue));
self.insert = newValue;
[self _recomputeFastPathEligible];
}

- (void)terminalActiveCharsetDidChangeTo:(int)charset {
[self _recomputeFastPathEligible];
}

- (int)terminalChecksumInRectangle:(VT100GridRect)rect {
Expand Down
34 changes: 34 additions & 0 deletions sources/VT100ScreenMutableState.m
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ - (instancetype)initWithSideEffectPerformer:(id<VT100ScreenSideEffectPerforming>
_promptStateMachine.delegate = self;
_kittyImageController = [[iTermKittyImageController alloc] init];
_kittyImageController.delegate = self;
[self _recomputeFastPathEligible];
}
return self;
}
Expand Down Expand Up @@ -205,6 +206,7 @@ - (void)setTerminalEnabled:(BOOL)enabled {
self.ansi = self.terminal.isAnsi;
self.wraparoundMode = self.terminal.wraparoundMode;
self.insert = self.terminal.insertMode;
[self _recomputeFastPathEligible];
_commandRangeChangeJoiner = [iTermIdempotentOperationJoiner joinerWithScheduler:_tokenExecutor];
_terminal.delegate = self;
_tokenExecutor.delegate = self;
Expand Down Expand Up @@ -476,6 +478,7 @@ - (void)setConfig:(VT100MutableScreenConfiguration *)config {
[_promptStateMachine revealOrDismissComposerAgain];
}
_tokenExecutor.isBackgroundSession = !config.sessionIsVisible;
[self _recomputeFastPathEligible];
}

- (void)movePromptUnderComposerIfNeeded {
Expand Down Expand Up @@ -981,6 +984,26 @@ - (BOOL)shouldConvertCharactersToGraphicsCharacterSetInTerminal:(VT100Terminal *
return [self.charsetUsesLineDrawingMode containsObject:@(terminal.charset)];
}

// Mutation queue only
- (BOOL)_computeFastPathEligible {
return (!_collectInputForPrinting &&
!_triggerEvaluator.haveTriggersOrExpectations &&
!self.config.loggingEnabled &&
_postTriggerActions.count == 0 &&
![self shouldConvertCharactersToGraphicsCharacterSetInTerminal:self.terminal] &&
!self.config.publishing &&
self.commandStartCoord.x == -1 &&
self.wraparoundMode &&
!self.ansi &&
!self.insert &&
self.currentGrid == self.primaryGrid);
}

// Mutation queue only
- (void)_recomputeFastPathEligible {
_fastPathEligible = [self _computeFastPathEligible];
}

- (void)reverseIndex {
if (self.currentGrid.cursorY == self.currentGrid.topMargin) {
if (self.cursorOutsideLeftRightMargin) {
Expand Down Expand Up @@ -1945,6 +1968,7 @@ - (void)showAltBuffer {
[self hideOnScreenNotesAndTruncateSpanners];
self.currentGrid = self.altGrid;
self.currentGrid.cursor = self.primaryGrid.cursor;
[self _recomputeFastPathEligible];

[self swapOnscreenIntervalTreeObjects];
[self reloadMarkCache];
Expand All @@ -1965,6 +1989,7 @@ - (void)showPrimaryBuffer {
[self.temporaryDoubleBuffer reset];
[self hideOnScreenNotesAndTruncateSpanners];
self.currentGrid = self.primaryGrid;
[self _recomputeFastPathEligible];
[self invalidateCommandStartCoordWithoutSideEffects];
[self swapOnscreenIntervalTreeObjects];
[self reloadMarkCache];
Expand Down Expand Up @@ -2214,6 +2239,7 @@ - (void)setCharacterSet:(int)charset usesLineDrawingMode:(BOOL)lineDrawingMode {
} else {
[self.charsetUsesLineDrawingMode removeObject:@(charset)];
}
[self _recomputeFastPathEligible];
}

#pragma mark - Tabs
Expand Down Expand Up @@ -3320,6 +3346,7 @@ - (void)setHost:(NSString *)host

- (void)setCoordinateOfCommandStart:(VT100GridAbsCoord)coord {
self.commandStartCoord = coord;
[self _recomputeFastPathEligible];
[self didUpdatePromptLocation];
[self commandRangeDidChange];
}
Expand Down Expand Up @@ -3406,6 +3433,7 @@ - (void)removePromptMarksBelowLine:(int)line {

- (void)setCommandStartCoordWithoutSideEffects:(VT100GridAbsCoord)coord {
self.commandStartCoord = coord;
[self _recomputeFastPathEligible];
}

- (void)invalidateCommandStartCoordWithoutSideEffects {
Expand Down Expand Up @@ -4590,6 +4618,7 @@ - (void)injectData:(NSData *)data {

- (void)evaluateTriggers:(void (^ NS_NOESCAPE)(PTYTriggerEvaluator *triggerEvaluator))block {
block(_triggerEvaluator);
[self _recomputeFastPathEligible];
if (_tokenExecutor.isExecutingToken) {
return;
}
Expand All @@ -4602,6 +4631,7 @@ - (void)executePostTriggerActions {
}
NSArray<void (^)(void)> *actions = [_postTriggerActions copy];
[_postTriggerActions removeAllObjects];
[self _recomputeFastPathEligible];
for (void (^block)(void) in actions) {
block();
}
Expand Down Expand Up @@ -4860,6 +4890,7 @@ - (void)updateExpectFrom:(iTermExpect *)source {
DLog(@"Update expect %@", source);
_triggerEvaluator.expect = [source copy];
DLog(@"Mutation thread expectations are now %@", _triggerEvaluator.expect);
[self _recomputeFastPathEligible];
}

- (void)performLightweightBlockWithJoinedThreads:(void (^ NS_NOESCAPE)(VT100ScreenMutableState *mutableState))block {
Expand Down Expand Up @@ -5137,6 +5168,7 @@ - (void)restoreFromDictionary:(NSDictionary *)dictionary
}
DLog(@"------------ end -----------");
}
[self _recomputeFastPathEligible];
}
}

Expand Down Expand Up @@ -5341,6 +5373,7 @@ - (void)restoreFromSavedState:(NSDictionary *)terminalState {
if (path) {
[self setPathFromURL:path];
}
[self _recomputeFastPathEligible];
}

#pragma mark - iTermMarkDelegate
Expand Down Expand Up @@ -6065,6 +6098,7 @@ - (void)triggerSession:(Trigger *)trigger didDetectPromptAtAbsLine:(long long)li
[_postTriggerActions addObject:[^{
[weakSelf handleTriggerDetectedPromptAt:range];
} copy]];
[self _recomputeFastPathEligible];
if (_tokenExecutor.isExecutingToken) {
self.terminal.wantsDidExecuteCallback = YES;
}
Expand Down
7 changes: 5 additions & 2 deletions sources/VT100Terminal.m
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,11 @@ - (void)setSendReceiveMode:(BOOL)sendReceiveMode {
}

- (void)setCharset:(int)charset {
self.dirty = YES;
_charset = charset;
if (_charset != charset) {
self.dirty = YES;
_charset = charset;
[_delegate terminalActiveCharsetDidChangeTo:charset];
}
}

- (void)setCursorMode:(BOOL)cursorMode {
Expand Down
1 change: 1 addition & 0 deletions sources/VT100TerminalDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ typedef NS_ENUM(NSUInteger, VT100TerminalProtectedMode) {
- (void)terminalWraparoundModeDidChangeTo:(BOOL)newValue;
- (void)terminalTypeDidChange;
- (void)terminalInsertModeDidChangeTo:(BOOL)newValue;
- (void)terminalActiveCharsetDidChangeTo:(int)charset;

- (NSString *)terminalProfileName;

Expand Down