Skip to content

Commit 6598166

Browse files
committed
Emit a tokens change event only if there are changed tokens
1 parent 9931bab commit 6598166

2 files changed

Lines changed: 51 additions & 8 deletions

File tree

src/vs/editor/common/model/textModel.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,7 @@ export class TextModel extends Disposable implements model.ITextModel {
17131713
throw new Error('Illegal value for lineNumber');
17141714
}
17151715

1716-
this._tokens.setTokens(this._languageIdentifier.id, lineNumber - 1, this._buffer.getLineLength(lineNumber), tokens);
1716+
this._tokens.setTokens(this._languageIdentifier.id, lineNumber - 1, this._buffer.getLineLength(lineNumber), tokens, false);
17171717
}
17181718

17191719
public setTokens(tokens: MultilineTokens[]): void {
@@ -1725,16 +1725,34 @@ export class TextModel extends Disposable implements model.ITextModel {
17251725

17261726
for (let i = 0, len = tokens.length; i < len; i++) {
17271727
const element = tokens[i];
1728-
ranges.push({ fromLineNumber: element.startLineNumber, toLineNumber: element.startLineNumber + element.tokens.length - 1 });
1728+
let minChangedLineNumber = 0;
1729+
let maxChangedLineNumber = 0;
1730+
let hasChange = false;
17291731
for (let j = 0, lenJ = element.tokens.length; j < lenJ; j++) {
1730-
this.setLineTokens(element.startLineNumber + j, element.tokens[j]);
1732+
const lineNumber = element.startLineNumber + j;
1733+
if (hasChange) {
1734+
this._tokens.setTokens(this._languageIdentifier.id, lineNumber - 1, this._buffer.getLineLength(lineNumber), element.tokens[j], false);
1735+
maxChangedLineNumber = lineNumber;
1736+
} else {
1737+
const lineHasChange = this._tokens.setTokens(this._languageIdentifier.id, lineNumber - 1, this._buffer.getLineLength(lineNumber), element.tokens[j], true);
1738+
if (lineHasChange) {
1739+
hasChange = true;
1740+
minChangedLineNumber = lineNumber;
1741+
maxChangedLineNumber = lineNumber;
1742+
}
1743+
}
1744+
}
1745+
if (hasChange) {
1746+
ranges.push({ fromLineNumber: minChangedLineNumber, toLineNumber: maxChangedLineNumber });
17311747
}
17321748
}
17331749

1734-
this._emitModelTokensChangedEvent({
1735-
tokenizationSupportChanged: false,
1736-
ranges: ranges
1737-
});
1750+
if (ranges.length > 0) {
1751+
this._emitModelTokensChangedEvent({
1752+
tokenizationSupportChanged: false,
1753+
ranges: ranges
1754+
});
1755+
}
17381756
}
17391757

17401758
public setSemanticTokens(tokens: MultilineTokens2[] | null): void {

src/vs/editor/common/model/tokensStore.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,10 +964,35 @@ export class TokensStore {
964964
this._len += insertCount;
965965
}
966966

967-
public setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, _tokens: Uint32Array | ArrayBuffer | null): void {
967+
public setTokens(topLevelLanguageId: LanguageId, lineIndex: number, lineTextLength: number, _tokens: Uint32Array | ArrayBuffer | null, checkEquality: boolean): boolean {
968968
const tokens = TokensStore._massageTokens(topLevelLanguageId, lineTextLength, _tokens);
969969
this._ensureLine(lineIndex);
970+
const oldTokens = this._lineTokens[lineIndex];
970971
this._lineTokens[lineIndex] = tokens;
972+
973+
if (checkEquality) {
974+
return !TokensStore._equals(oldTokens, tokens);
975+
}
976+
return false;
977+
}
978+
979+
private static _equals(_a: Uint32Array | ArrayBuffer | null, _b: Uint32Array | ArrayBuffer | null) {
980+
if (!_a || !_b) {
981+
return !_a && !_b;
982+
}
983+
984+
const a = toUint32Array(_a);
985+
const b = toUint32Array(_b);
986+
987+
if (a.length !== b.length) {
988+
return false;
989+
}
990+
for (let i = 0, len = a.length; i < len; i++) {
991+
if (a[i] !== b[i]) {
992+
return false;
993+
}
994+
}
995+
return true;
971996
}
972997

973998
//#region Editing

0 commit comments

Comments
 (0)