Skip to content

Commit

Permalink
TextBuffer API: getNearestChunk to support incremental tree sitter pa…
Browse files Browse the repository at this point in the history
…rsing. (#214648)
  • Loading branch information
rebornix authored Jun 7, 2024
1 parent dc97013 commit 30f0c14
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/vs/editor/common/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,11 @@ export interface IReadonlyTextBuffer {
getLineFirstNonWhitespaceColumn(lineNumber: number): number;
getLineLastNonWhitespaceColumn(lineNumber: number): number;
findMatchesLineByLine(searchRange: Range, searchData: SearchData, captureMatches: boolean, limitResultCount: number): FindMatch[];

/**
* Get nearest chunk of text after `offset` in the text buffer.
*/
getNearestChunk(offset: number): string;
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,27 @@ export class PieceTreeBase {
return this._getCharCode(nodePos);
}

public getNearestChunk(offset: number): string {
const nodePos = this.nodeAt(offset);
if (nodePos.remainder === nodePos.node.piece.length) {
// the offset is at the head of next node.
const matchingNode = nodePos.node.next();
if (!matchingNode || matchingNode === SENTINEL) {
return '';
}

const buffer = this._buffers[matchingNode.piece.bufferIndex];
const startOffset = this.offsetInBuffer(matchingNode.piece.bufferIndex, matchingNode.piece.start);
return buffer.buffer.substring(startOffset, startOffset + matchingNode.piece.length);
} else {
const buffer = this._buffers[nodePos.node.piece.bufferIndex];
const startOffset = this.offsetInBuffer(nodePos.node.piece.bufferIndex, nodePos.node.piece.start);
const targetOffset = startOffset + nodePos.remainder;
const targetEnd = startOffset + nodePos.node.piece.length;
return buffer.buffer.substring(targetOffset, targetEnd);
}
}

public findMatchesInNode(node: TreeNode, searcher: Searcher, startLineNumber: number, startColumn: number, startCursor: BufferCursor, endCursor: BufferCursor, searchData: SearchData, captureMatches: boolean, limitResultCount: number, resultLen: number, result: FindMatch[]) {
const buffer = this._buffers[node.piece.bufferIndex];
const startOffsetInBuffer = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ export class PieceTreeTextBuffer extends Disposable implements ITextBuffer {
return this.getValueLengthInRange(range, eol);
}

public getNearestChunk(offset: number): string {
return this._pieceTree.getNearestChunk(offset);
}

public getLength(): number {
return this._pieceTree.getLength();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,22 @@ suite('buffer api', () => {
assert.strictEqual(pieceTable.getLineCharCode(2, 3), 'e'.charCodeAt(0), 'e');
assert.strictEqual(pieceTable.getLineCharCode(2, 4), '2'.charCodeAt(0), '2');
});

test('getNearestChunk', () => {
const pieceTree = createTextBuffer(['012345678']);
ds.add(pieceTree);
const pt = pieceTree.getPieceTree();

pt.insert(3, 'ABC');
assert.equal(pt.getLineContent(1), '012ABC345678');
assert.equal(pt.getNearestChunk(3), 'ABC');
assert.equal(pt.getNearestChunk(6), '345678');

pt.delete(9, 1);
assert.equal(pt.getLineContent(1), '012ABC34578');
assert.equal(pt.getNearestChunk(6), '345');
assert.equal(pt.getNearestChunk(9), '78');
});
});

suite('search offset cache', () => {
Expand Down

0 comments on commit 30f0c14

Please sign in to comment.