Skip to content
Draft
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
8 changes: 8 additions & 0 deletions src/extension/xtab/node/xtabProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,14 @@ export class XtabProvider implements IStatelessNextEditProvider {
return noSuggestions;
}

// Skip next cursor prediction when edit window already covers the entire file
const entireFileRange = OffsetRange.ofLength(promptPieces.currentDocument.lines.length);
if (promptPieces.editWindowLinesRange.containsRange(entireFileRange)) {
tracer.trace('Skipping next cursor prediction: edit window covers entire file');
telemetryBuilder.setNextCursorLineError('editWindowCoversWholeFile');
return noSuggestions;
}

const nextCursorLineR = await this.nextCursorPredictor.predictNextCursorPosition(promptPieces, tracer, telemetryBuilder, cancellationToken);

if (cancellationToken.isCancellationRequested) {
Expand Down
58 changes: 58 additions & 0 deletions src/extension/xtab/test/node/xtabProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,64 @@ import { expect, suite, test } from 'vitest';
import { findMergeConflictMarkersRange } from '../../node/xtabProvider';
import { OffsetRange } from '../../../../util/vs/editor/common/core/ranges/offsetRange';

suite('editWindowCoversWholeFile check', () => {
test('should detect when edit window covers the entire file', () => {
const documentLines = 5;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(0, 5);

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(true);
});

test('should not trigger when edit window is smaller than file', () => {
const documentLines = 10;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(2, 6); // Only covers lines 2-5

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(false);
});

test('should detect when edit window is larger than file (edge case)', () => {
const documentLines = 3;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(0, 10); // Larger than file

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(true);
});

test('should not trigger when edit window starts at 0 but does not reach end', () => {
const documentLines = 10;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(0, 5); // Only covers first half

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(false);
});

test('should not trigger when edit window reaches end but does not start at 0', () => {
const documentLines = 10;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(5, 10); // Only covers second half

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(false);
});

test('should handle single-line file', () => {
const documentLines = 1;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(0, 1);

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(true);
});

test('should handle empty file', () => {
const documentLines = 0;
const entireFileRange = OffsetRange.ofLength(documentLines);
const editWindowLinesRange = new OffsetRange(0, 0);

expect(editWindowLinesRange.containsRange(entireFileRange)).toBe(true);
});
});

suite('findMergeConflictMarkersRange', () => {

test('should find merge conflict markers within edit window', () => {
Expand Down