diff --git a/iTerm2XCTests/VT100GridTest.m b/iTerm2XCTests/VT100GridTest.m index 327b376d90..36457246bc 100644 --- a/iTerm2XCTests/VT100GridTest.m +++ b/iTerm2XCTests/VT100GridTest.m @@ -1805,7 +1805,7 @@ - (void)testResetWithLineBufferLeavingBehindZero { [lineBuffer setMaxLines:1]; int dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:NO - preserveCursorLine:NO]; + preservePromptLines:0]; XCTAssert(dropped == 2); XCTAssert([[grid compactLineDump] isEqualToString: @"....\n" @@ -1826,7 +1826,7 @@ - (void)testResetWithLineBufferLeavingBehindZero { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:YES - preserveCursorLine:NO]; + preservePromptLines:0]; XCTAssert(dropped == 0); XCTAssert([[grid compactLineDump] isEqualToString: @"....\n" @@ -1841,7 +1841,7 @@ - (void)testResetWithLineBufferLeavingBehindZero { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:YES - preserveCursorLine:NO]; + preservePromptLines:0]; XCTAssert(dropped == 0); XCTAssert([[grid compactLineDump] isEqualToString: @"..\n" @@ -1861,7 +1861,7 @@ - (void)testResetWithLineBufferLeavingBehindCursorLine { [lineBuffer setMaxLines:1]; int dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:NO - preserveCursorLine:YES]; + preservePromptLines:1]; XCTAssert(dropped == 2); XCTAssert([[grid compactLineDump] isEqualToString: @"....\n" @@ -1887,7 +1887,7 @@ - (void)testResetWithLineBufferLeavingBehindCursorLine { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:NO - preserveCursorLine:YES]; + preservePromptLines:1]; XCTAssert(dropped == 1); XCTAssert([[grid compactLineDump] isEqualToString: @"efgh\n" @@ -1913,7 +1913,7 @@ - (void)testResetWithLineBufferLeavingBehindCursorLine { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:NO - preserveCursorLine:YES]; + preservePromptLines:1]; XCTAssert(dropped == 0); XCTAssert([[grid compactLineDump] isEqualToString: @"abcd\n" @@ -1935,7 +1935,7 @@ - (void)testResetWithLineBufferLeavingBehindCursorLine { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:YES - preserveCursorLine:YES]; + preservePromptLines:1]; XCTAssert(dropped == 0); XCTAssert([[grid compactLineDump] isEqualToString: @"....\n" @@ -1950,7 +1950,7 @@ - (void)testResetWithLineBufferLeavingBehindCursorLine { [lineBuffer setMaxLines:1]; dropped = [grid resetWithLineBuffer:lineBuffer unlimitedScrollback:YES - preserveCursorLine:YES]; + preservePromptLines:1]; XCTAssert(dropped == 0); XCTAssert([[grid compactLineDump] isEqualToString: @"..\n" diff --git a/sources/VT100Grid.h b/sources/VT100Grid.h index a8ef6134be..fd4732015c 100644 --- a/sources/VT100Grid.h +++ b/sources/VT100Grid.h @@ -128,7 +128,7 @@ // for |leave|. - (int)resetWithLineBuffer:(LineBuffer *)lineBuffer unlimitedScrollback:(BOOL)unlimitedScrollback - preserveCursorLine:(BOOL)preserveCursorLine; + preservePromptLines:(int)preservePromptLines; // Move the grid contents up, leaving only the whole wrapped line the cursor is on at the top. - (void)moveWrappedCursorLineToTopOfGrid; diff --git a/sources/VT100Grid.m b/sources/VT100Grid.m index a8836249f5..169f8780a9 100644 --- a/sources/VT100Grid.m +++ b/sources/VT100Grid.m @@ -388,12 +388,12 @@ - (int)scrollUpIntoLineBuffer:(LineBuffer *)lineBuffer - (int)resetWithLineBuffer:(LineBuffer *)lineBuffer unlimitedScrollback:(BOOL)unlimitedScrollback - preserveCursorLine:(BOOL)preserveCursorLine { + preservePromptLines:(int)preservePromptLines { self.scrollRegionRows = VT100GridRangeMake(0, size_.height); self.scrollRegionCols = VT100GridRangeMake(0, size_.width); int numLinesToScroll; - if (preserveCursorLine) { - numLinesToScroll = cursor_.y; + if (preservePromptLines > 0 && preservePromptLines < size_.height) { + numLinesToScroll = MAX(0, cursor_.y - preservePromptLines + 1); } else { numLinesToScroll = [self lineNumberOfLastNonEmptyLine] + 1; } @@ -405,7 +405,7 @@ - (int)resetWithLineBuffer:(LineBuffer *)lineBuffer } self.cursor = VT100GridCoordMake(0, 0); - [self setCharsFrom:VT100GridCoordMake(0, preserveCursorLine ? 1 : 0) + [self setCharsFrom:VT100GridCoordMake(0, preservePromptLines) to:VT100GridCoordMake(size_.width - 1, size_.height - 1) toChar:[self defaultChar]]; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 96a47f9a3b..2398b4a18a 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -848,13 +848,30 @@ - (void)clearBuffer { // This clears the screen, leaving the cursor's line at the top and preserves the cursor's x // coordinate. Scroll regions and the saved cursor position are reset. - (void)clearAndResetScreenPreservingCursorLine { + int numberOfLinesInPrompt; + if (_shellIntegrationInstalled) { + numberOfLinesInPrompt = currentGrid_.cursorY + [self numberOfScrollbackLines] + [self totalScrollbackOverflow] - _lastCommandOutputRange.end.y + 1; + DLog(@"numberOfLinesInPrompt calculated (based on shell integration): %d", numberOfLinesInPrompt); + } else { + numberOfLinesInPrompt = [iTermAdvancedSettingsModel numberOfLinesInPrompt]; + DLog(@"numberOfLinesInPrompt taken from advanced settings: %d", numberOfLinesInPrompt); + } + + if (numberOfLinesInPrompt <= 0) { + DLog(@"iTerm advanced settings variable 'numberOfLinesInPrompt' is equal or less than than zero: %d", numberOfLinesInPrompt); + numberOfLinesInPrompt = 1; + } else if (numberOfLinesInPrompt > 3) { + DLog(@"iTerm advanced settings variable 'numberOfLinesInPrompt' is greater than 3: %d", numberOfLinesInPrompt); + } + [delegate_ screenTriggerableChangeDidOccur]; // This clears the screen. int x = currentGrid_.cursorX; [self incrementOverflowBy:[currentGrid_ resetWithLineBuffer:linebuffer_ unlimitedScrollback:unlimitedScrollback_ - preserveCursorLine:YES]]; + preservePromptLines:numberOfLinesInPrompt]]; currentGrid_.cursorX = x; + currentGrid_.cursorY = numberOfLinesInPrompt - 1; } - (void)clearScrollbackBuffer @@ -2586,7 +2603,7 @@ - (void)terminalResetPreservingPrompt:(BOOL)preservePrompt { } else { [self incrementOverflowBy:[currentGrid_ resetWithLineBuffer:linebuffer_ unlimitedScrollback:unlimitedScrollback_ - preserveCursorLine:NO]]; + preservePromptLines:0]]; } [self setInitialTabStops]; diff --git a/sources/iTermAdvancedSettingsModel.h b/sources/iTermAdvancedSettingsModel.h index 8a1ec32490..05615ebbd7 100644 --- a/sources/iTermAdvancedSettingsModel.h +++ b/sources/iTermAdvancedSettingsModel.h @@ -106,6 +106,7 @@ + (BOOL)useOpenDirectory; + (BOOL)disallowCopyEmptyString; + (BOOL)profilesWindowJoinsActiveSpace; ++ (int)numberOfLinesInPrompt; + (NSString *)badgeFont; + (BOOL)badgeFontIsBold; diff --git a/sources/iTermAdvancedSettingsModel.m b/sources/iTermAdvancedSettingsModel.m index 905c8bdd8b..cbbf14eeb3 100644 --- a/sources/iTermAdvancedSettingsModel.m +++ b/sources/iTermAdvancedSettingsModel.m @@ -83,6 +83,7 @@ + (NSString *)name { \ DEFINE_INT(triggerRadius, 3, @"Terminal: Number of screen lines to match against trigger regular expressions.\nTrigger regular expressions are matched against the last logical line of text when a newline is received. A search is performed to find the start of the line. Since very long lines would cause performance problems, the search (and consequently the regular expression match, highlighting, and so on) is limited to this many screen lines."); DEFINE_BOOL(requireCmdForDraggingText, NO, @"Terminal: To drag images or selected text, you must hold ⌘. This prevents accidental drags."); DEFINE_BOOL(focusReportingEnabled, YES, @"Terminal: Apps may turn on Focus Reporting.\nFocus reporting causes iTerm2 to send an escape sequence when a session gains or loses focus. It can cause problems when an ssh session dies unexpectedly because it gets left on, so some users prefer to disable it."); +DEFINE_INT(numberOfLinesInPrompt, 1, @"Terminal: Number of lines in prompt.\n\"Clear Buffer\" command clears all output except prompt lines. If prompt consist of more than one line, all lines except last will be cleared. You could set this variable to prompt lines count to avoid this behavior. This param is ignored if Shell Integration is installed."); #pragma mark Hotkey DEFINE_FLOAT(hotkeyTermAnimationDuration, 0.25, @"Hotkey: Duration in seconds of the hotkey window animation.\nWarning: reducing this value may cause problems if you have multiple displays.");