Skip to content

Commit 41933fa

Browse files
authored
Fix issue with incorrect colorization immediately after saving a new file (#4153)
1 parent c03fea0 commit 41933fa

File tree

2 files changed

+51
-40
lines changed

2 files changed

+51
-40
lines changed

Extension/src/LanguageServer/client.ts

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ export interface Client {
296296
TrackedDocuments: Set<vscode.TextDocument>;
297297
onDidChangeSettings(event: vscode.ConfigurationChangeEvent): { [key: string] : string };
298298
onDidOpenTextDocument(document: vscode.TextDocument): void;
299+
onDidCloseTextDocument(document: vscode.TextDocument): void;
299300
onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void;
300301
onDidChangeTextDocument(textDocumentChangeEvent: vscode.TextDocumentChangeEvent): void;
301302
onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void;
@@ -360,6 +361,7 @@ class DefaultClient implements Client {
360361
private isSupported: boolean = true;
361362
private colorizationSettings: ColorizationSettings;
362363
private colorizationState = new Map<string, ColorizationState>();
364+
private openFileVersions = new Map<string, number>();
363365
private visibleRanges = new Map<string, Range[]>();
364366
private settingsTracker: SettingsTracker;
365367
private configurationProvider: string;
@@ -659,36 +661,49 @@ class DefaultClient implements Client {
659661
this.editVersion++;
660662
if (textDocumentChangeEvent.document.uri.scheme === "file") {
661663
if (textDocumentChangeEvent.document.languageId === "cpp" || textDocumentChangeEvent.document.languageId === "c") {
662-
try {
663-
let colorizationState: ColorizationState = this.getColorizationState(textDocumentChangeEvent.document.uri.toString());
664-
665-
// Adjust colorization ranges after this edit. (i.e. if a line was added, push decorations after it down one line)
666-
colorizationState.addEdits(textDocumentChangeEvent.contentChanges, this.editVersion);
667-
} catch (e) {
668-
// Ensure an exception does not prevent pass-through to native handler, or editVersion could become inconsistent
669-
console.log(e.toString());
664+
let oldVersion: number = this.openFileVersions.get(textDocumentChangeEvent.document.uri.toString());
665+
let newVersion: number = textDocumentChangeEvent.document.version;
666+
if (newVersion > oldVersion) {
667+
this.openFileVersions.set(textDocumentChangeEvent.document.uri.toString(), newVersion);
668+
try {
669+
let colorizationState: ColorizationState = this.colorizationState.get(textDocumentChangeEvent.document.uri.toString());
670+
if (colorizationState) {
671+
// Adjust colorization ranges after this edit. (i.e. if a line was added, push decorations after it down one line)
672+
colorizationState.addEdits(textDocumentChangeEvent.contentChanges, this.editVersion);
673+
}
674+
} catch (e) {
675+
// Ensure an exception does not prevent pass-through to native handler, or editVersion could become inconsistent
676+
console.log(e.toString());
677+
}
670678
}
671679
}
672680
}
673681
}
674682

675683
public onDidOpenTextDocument(document: vscode.TextDocument): void {
676684
if (document.uri.scheme === "file") {
685+
this.openFileVersions.set(document.uri.toString(), document.version);
686+
this.colorizationState.set(document.uri.toString(), new ColorizationState(document.uri, this.colorizationSettings));
677687
this.sendVisibleRanges(document.uri);
678688
}
679689
}
680690

691+
public onDidCloseTextDocument(document: vscode.TextDocument): void {
692+
this.colorizationState.delete(document.uri.toString());
693+
this.openFileVersions.delete(document.uri.toString());
694+
}
695+
681696
public onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {
682697
let processedUris: vscode.Uri[] = [];
683698
editors.forEach(editor => {
684699
if (editor.document.uri.scheme === "file") {
685700
let colorizationState: ColorizationState = this.colorizationState.get(editor.document.uri.toString());
686701
if (colorizationState) {
687702
colorizationState.refresh(editor);
688-
}
689-
if (!processedUris.find(uri => uri === editor.document.uri)) {
690-
processedUris.push(editor.document.uri);
691-
this.sendVisibleRanges(editor.document.uri);
703+
if (!processedUris.find(uri => uri === editor.document.uri)) {
704+
processedUris.push(editor.document.uri);
705+
this.sendVisibleRanges(editor.document.uri);
706+
}
692707
}
693708
}
694709
});
@@ -1362,33 +1377,26 @@ class DefaultClient implements Client {
13621377
this.model.tagParserStatus.Value = notificationBody.status;
13631378
}
13641379

1365-
private getColorizationState(uri: string): ColorizationState {
1366-
let colorizationState: ColorizationState = this.colorizationState.get(uri);
1367-
if (!colorizationState) {
1368-
colorizationState = new ColorizationState(this.RootUri, this.colorizationSettings);
1369-
this.colorizationState.set(uri, colorizationState);
1370-
}
1371-
return colorizationState;
1372-
}
1373-
13741380
private updateSemanticColorizationRegions(params: SemanticColorizationRegionsParams): void {
1375-
// Convert the params to vscode.Range's before passing to colorizationState.updateSemantic()
1376-
let semanticRanges: vscode.Range[][] = new Array<vscode.Range[]>(TokenKind.Count);
1377-
for (let i: number = 0; i < TokenKind.Count; i++) {
1378-
semanticRanges[i] = [];
1381+
let colorizationState: ColorizationState = this.colorizationState.get(params.uri);
1382+
if (colorizationState) {
1383+
// Convert the params to vscode.Range's before passing to colorizationState.updateSemantic()
1384+
let semanticRanges: vscode.Range[][] = new Array<vscode.Range[]>(TokenKind.Count);
1385+
for (let i: number = 0; i < TokenKind.Count; i++) {
1386+
semanticRanges[i] = [];
1387+
}
1388+
params.regions.forEach(element => {
1389+
let newRange : vscode.Range = new vscode.Range(element.range.start.line, element.range.start.character, element.range.end.line, element.range.end.character);
1390+
semanticRanges[element.kind].push(newRange);
1391+
});
1392+
let inactiveRanges: vscode.Range[] = [];
1393+
params.inactiveRegions.forEach(element => {
1394+
let newRange : vscode.Range = new vscode.Range(element.startLine, 0, element.endLine, 0);
1395+
inactiveRanges.push(newRange);
1396+
});
1397+
colorizationState.updateSemantic(params.uri, semanticRanges, inactiveRanges, params.editVersion);
1398+
this.languageClient.sendNotification(SemanticColorizationRegionsReceiptNotification, { uri: params.uri });
13791399
}
1380-
params.regions.forEach(element => {
1381-
let newRange : vscode.Range = new vscode.Range(element.range.start.line, element.range.start.character, element.range.end.line, element.range.end.character);
1382-
semanticRanges[element.kind].push(newRange);
1383-
});
1384-
let inactiveRanges: vscode.Range[] = [];
1385-
params.inactiveRegions.forEach(element => {
1386-
let newRange : vscode.Range = new vscode.Range(element.startLine, 0, element.endLine, 0);
1387-
inactiveRanges.push(newRange);
1388-
});
1389-
let colorizationState: ColorizationState = this.getColorizationState(params.uri);
1390-
colorizationState.updateSemantic(params.uri, semanticRanges, inactiveRanges, params.editVersion);
1391-
this.languageClient.sendNotification(SemanticColorizationRegionsReceiptNotification, { uri: params.uri });
13921400
}
13931401

13941402
private promptCompileCommands(params: CompileCommandsPaths) : void {
@@ -2007,6 +2015,7 @@ class NullClient implements Client {
20072015
TrackedDocuments = new Set<vscode.TextDocument>();
20082016
onDidChangeSettings(event: vscode.ConfigurationChangeEvent): { [key: string] : string } { return {}; }
20092017
onDidOpenTextDocument(document: vscode.TextDocument): void {}
2018+
onDidCloseTextDocument(document: vscode.TextDocument): void {}
20102019
onDidChangeVisibleTextEditors(editors: vscode.TextEditor[]): void {}
20112020
onDidChangeTextDocument(textDocumentChangeEvent: vscode.TextDocumentChangeEvent): void {}
20122021
onDidChangeTextEditorVisibleRanges(textEditorVisibleRangesChangeEvent: vscode.TextEditorVisibleRangesChangeEvent): void {}

Extension/src/LanguageServer/protocolFilter.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ export function createProtocolFilter(me: Client, clients: ClientCollection): Mid
3232
me.addFileAssociations(mappingString, false);
3333
}
3434

35-
me.onDidOpenTextDocument(document);
36-
3735
me.provideCustomConfiguration(document.uri, null);
38-
me.notifyWhenReady(() => sendMessage(document));
36+
me.notifyWhenReady(() => {
37+
me.onDidOpenTextDocument(document);
38+
sendMessage(document);
39+
});
3940
}
4041
},
4142
didChange: (textDocumentChangeEvent, sendMessage) => {
@@ -55,6 +56,7 @@ export function createProtocolFilter(me: Client, clients: ClientCollection): Mid
5556
didClose: (document, sendMessage) => {
5657
if (clients.ActiveClient === me) {
5758
console.assert(me.TrackedDocuments.has(document));
59+
me.onDidCloseTextDocument(document);
5860
me.TrackedDocuments.delete(document);
5961
me.notifyWhenReady(() => sendMessage(document));
6062
}

0 commit comments

Comments
 (0)