Skip to content
Closed
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
61 changes: 61 additions & 0 deletions ModernTests/VT100ScreenTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,67 @@ class VT100ScreenTests: XCTestCase {
})
}

func testCommandMarkAtReturnsNilWhenLineIsOutOfBounds() {
let screen = self.screen(width: 10, height: 4)

screen.performBlock(joinedThreads: { _, mutableState, _ in
var range = VT100GridWindowedRange()
let negative = mutableState.commandMark(at: VT100GridCoordMake(0, -1),
mustHaveCommand: false,
range: &range)
XCTAssertNil(negative)

let tooLargeY = mutableState.numberOfLines
let tooLarge = mutableState.commandMark(at: VT100GridCoordMake(0, tooLargeY),
mustHaveCommand: false,
range: &range)
XCTAssertNil(tooLarge)
})
}

func testCommandMarkAtReturnsNilWhenNoMarkOnLine() {
let screen = self.screen(width: 10, height: 4)

appendLinesNoNewline([
"https://example.com",
"next line"
], screen: screen)

screen.performBlock(joinedThreads: { _, mutableState, _ in
var range = VT100GridWindowedRange()
let mark = mutableState.commandMark(at: VT100GridCoordMake(0, 0),
mustHaveCommand: false,
range: &range)
XCTAssertNil(mark)
})
}

func testCommandMarkAtReturnsNilWhenMarkHasNoCommand() {
let screen = self.screen(width: 10, height: 4)

appendLinesNoNewline([
"prompt",
"next line"
], screen: screen)

screen.performBlock(joinedThreads: { _, mutableState, _ in
let mark = mutableState.addMark(onLine: 0, of: VT100ScreenMark.self) as! VT100ScreenMark
let absLine = mutableState.cumulativeScrollbackOverflow
mutableState.mutableIntervalTree().mutate(mark) { obj in
let m = obj as! VT100ScreenMark
m.promptRange = VT100GridAbsCoordRangeMake(0, absLine, 6, absLine)
}

var range = VT100GridWindowedRange()
XCTAssertNotNil(mutableState.commandMark(at: VT100GridCoordMake(0, 0),
mustHaveCommand: false,
range: &range))
XCTAssertNil(mutableState.commandMark(at: VT100GridCoordMake(0, 0),
mustHaveCommand: true,
range: &range))
})
}

private func commonNoteResizeRegressionTest(initialRange range1: VT100GridCoordRange,
intermediateRange range2: VT100GridCoordRange) {
var screen = self.screen(width: 80, height: 25)
Expand Down
3 changes: 3 additions & 0 deletions docs/notes-3.7.txt
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ Bug Fixes:
Korean) in the AI Chat input no longer
prematurely submits the unfinalized
candidate text.
- Command-clicking links in terminal output
no longer crashes when command-mark data
is unavailable.
- Open Quickly now updates the MRU order
when you jump to a session, so repeated
Cmd-Shift-O Enter cycles between the two
Expand Down
15 changes: 14 additions & 1 deletion sources/VT100Screen/VT100ScreenState.m
Original file line number Diff line number Diff line change
Expand Up @@ -1251,8 +1251,21 @@ - (NSIndexSet *)foldsInRange:(VT100GridRange)gridRange {
- (id<VT100ScreenMarkReading>)commandMarkAt:(VT100GridCoord)coord
mustHaveCommand:(BOOL)mustHaveCommand
range:(out VT100GridWindowedRange *)rangeOut {
if (coord.y < 0 || coord.y >= self.numberOfLines) {
return nil;
}

id<VT100ScreenMarkReading> mark = [self screenMarkOnLine:coord.y];
const VT100GridCoordRange range = [self coordRangeForInterval:mark.entry.interval];
if (!mark) {
return nil;
}

IntervalTreeEntry *entry = mark.entry;
if (!entry || !entry.interval) {
return nil;
}

const VT100GridCoordRange range = [self coordRangeForInterval:entry.interval];
if (mustHaveCommand && mark.firstLineOfCommand == nil) {
return nil;
}
Expand Down