Skip to content

Commit

Permalink
Fix race in tree sitter where same ranges could be fired more than once
Browse files Browse the repository at this point in the history
  • Loading branch information
alexr00 committed Sep 18, 2024
1 parent b74236c commit 26d0ee9
Showing 1 changed file with 16 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,8 @@ export class TextModelTreeSitter extends Disposable {
}

private async _onDidChangeContent(treeSitterTree: TreeSitterParseResult, changes: IModelContentChange[]) {
const oldTree = treeSitterTree.tree?.copy();
await treeSitterTree.onDidChangeContent(this.model, changes);
if (oldTree && treeSitterTree.tree) {
const diff = oldTree.getChangedRanges(treeSitterTree.tree);
const diff = await treeSitterTree.onDidChangeContent(this.model, changes);
if (diff && diff.length > 0) {
// Tree sitter is 0 based, text model is 1 based
this._onDidChangeParseResult.fire(diff.map(r => new Range(r.startPosition.row + 1, r.startPosition.column + 1, r.endPosition.row + 1, r.endPosition.column + 1)));
}
Expand Down Expand Up @@ -143,18 +141,22 @@ export class TreeSitterParseResult implements IDisposable, ITreeSitterParseResul
get isDisposed() { return this._isDisposed; }

private _onDidChangeContentQueue: Promise<void> = Promise.resolve();
public async onDidChangeContent(model: ITextModel, changes: IModelContentChange[]) {
public async onDidChangeContent(model: ITextModel, changes: IModelContentChange[]): Promise<Parser.Range[] | undefined> {
const oldTree = this.tree?.copy();
this._applyEdits(model, changes);
this._onDidChangeContentQueue = this._onDidChangeContentQueue.then(() => {
if (this.isDisposed) {
// No need to continue the queue if we are disposed
return;
}
return this._parseAndUpdateTree(model);
}).catch((e) => {
this._logService.error('Error parsing tree-sitter tree', e);
return new Promise(resolve => {
this._onDidChangeContentQueue = this._onDidChangeContentQueue.then(async () => {
if (this.isDisposed) {
// No need to continue the queue if we are disposed
return;
}
await this._parseAndUpdateTree(model);
resolve(this.tree ? oldTree?.getChangedRanges(this.tree) : undefined);

}).catch((e) => {
this._logService.error('Error parsing tree-sitter tree', e);
});
});
return this._onDidChangeContentQueue;
}

private _newEdits = true;
Expand Down

0 comments on commit 26d0ee9

Please sign in to comment.