Compare commits

...
11 Commits
5 changed files with 83 additions and 46 deletions
+15
View File
@@ -1,5 +1,20 @@
# C/C++ for Visual Studio Code Changelog
## Version 1.19.8: March 13, 2024
### Bug Fixes
* Fix an issue with applying the proper working directory from a `compile_commands.json` when a `compilePath` is also set. [#12024](https://github.com/microsoft/vscode-cpptools/issues/12024)
* Fix a deadlock. [#12051](https://github.com/microsoft/vscode-cpptools/issues/12051)
* Fix a crash that could occur when failing to query clang-cl.
* Fix an issue with handling of `winsysroot` args for clang-cl.
* Fix an issue with processing relative include paths returned by clang-cl.
## Version 1.19.7: March 11, 2024
### Bug Fixes
* Fix some potential deadlocks. [#12051](https://github.com/microsoft/vscode-cpptools/issues/12051)
* Fix a crash related to parsing concepts. [#12060](https://github.com/microsoft/vscode-cpptools/issues/12060)
* Fix flickering status updates in the language status bar. [#12084](https://github.com/microsoft/vscode-cpptools/issues/12084)
* Fix a cpptools crash that can occur if cpptools-srv crashes on initialization.
## Version 1.19.6: March 6, 2024
### Enhancement
* Performance improvement.
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "cpptools",
"displayName": "C/C++",
"description": "C/C++ IntelliSense, debugging, and code browsing.",
"version": "1.19.6-main",
"version": "1.19.8-main",
"publisher": "ms-vscode",
"icon": "LanguageCCPP_color_128x.png",
"readme": "README.md",
+16 -11
View File
@@ -629,10 +629,13 @@ class ClientModel {
constructor() {
this.isInitializingWorkspace = new DataBinding<boolean>(false);
this.isIndexingWorkspace = new DataBinding<boolean>(false);
this.isParsingWorkspace = new DataBinding<boolean>(false);
this.isParsingWorkspacePaused = new DataBinding<boolean>(false);
this.isParsingFiles = new DataBinding<boolean>(false);
this.isUpdatingIntelliSense = new DataBinding<boolean>(false);
// The following elements add a delay of 500ms before notitfying the UI that the icon can hide itself.
this.isParsingWorkspace = new DataBinding<boolean>(false, 500, false);
this.isParsingWorkspacePaused = new DataBinding<boolean>(false, 500, false);
this.isParsingFiles = new DataBinding<boolean>(false, 500, false);
this.isUpdatingIntelliSense = new DataBinding<boolean>(false, 500, false);
this.isRunningCodeAnalysis = new DataBinding<boolean>(false);
this.isCodeAnalysisPaused = new DataBinding<boolean>(false);
this.codeAnalysisProcessed = new DataBinding<number>(0);
@@ -3689,9 +3692,9 @@ export class DefaultClient implements Client {
isReplace ? range.end.character :
range.end.character + edit.newText.length - rangeStartCharacter));
if (isSourceFile) {
sourceFormatUriAndRanges.push({uri, range: newFormatRange});
sourceFormatUriAndRanges.push({ uri, range: newFormatRange });
} else {
headerFormatUriAndRanges.push({uri, range: newFormatRange});
headerFormatUriAndRanges.push({ uri, range: newFormatRange });
}
if (isReplace || !isSourceFile) {
// Handle additional declaration lines added before the new function call.
@@ -3741,7 +3744,8 @@ export class DefaultClient implements Client {
// without being opened because otherwise users may not realize that
// the header had changed (unless they view source control differences).
await vscode.window.showTextDocument(headerFormatUriAndRanges[0].uri, {
selection: headerReplaceEditRange, preserveFocus: false });
selection: headerReplaceEditRange, preserveFocus: false
});
}
// Format the new text edits.
@@ -3785,8 +3789,7 @@ export class DefaultClient implements Client {
formatEdits.set(formatUriAndRange.uri, formatTextEdits);
return true;
};
if (!await tryFormat())
{
if (!await tryFormat()) {
await tryFormat(); // Try again;
}
};
@@ -3797,7 +3800,8 @@ export class DefaultClient implements Client {
// This showTextDocument is required in order to get the selection to be
// correct after the formatting edit is applied. It could be a VS Code bug.
await vscode.window.showTextDocument(headerFormatUriAndRanges[0].uri, {
selection: headerReplaceEditRange, preserveFocus: false });
selection: headerReplaceEditRange, preserveFocus: false
});
await vscode.workspace.applyEdit(formatEdits, { isRefactoring: true });
formatEdits = new vscode.WorkspaceEdit();
}
@@ -3805,7 +3809,8 @@ export class DefaultClient implements Client {
// Select the replaced code.
await vscode.window.showTextDocument(sourceFormatUriAndRanges[0].uri, {
selection: sourceReplaceEditRange, preserveFocus: false });
selection: sourceReplaceEditRange, preserveFocus: false
});
await formatRanges(sourceFormatUriAndRanges);
if (formatEdits.size > 0) {
+42 -5
View File
@@ -4,13 +4,37 @@
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
class Deferral {
private timer?: NodeJS.Timeout;
constructor(callback: () => void, timeout: number) {
this.timer = setTimeout(() => {
this.timer = undefined;
callback();
}, timeout);
}
public cancel() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
}
}
export class DataBinding<T> {
private value: T;
private valueChanged = new vscode.EventEmitter<T>();
private isActive: boolean = true;
private deferral?: Deferral;
constructor(value: T) {
this.value = value;
/**
* Bind an event to a value so that a data model can automatically update the UI when values change.
* Since values can change quickly and cause UI to flicker, an optional delay/trigger combination can
* be specified to prevent UI elements from appearing/disappearing too quickly.
* @param value The initial value in the binding.
* @param delay An optional delay (in milliseconds) for firing the value changed event.
* @param delayValueTrigger The value that triggers an event delay.
*/
constructor(private value: T, private delay: number = 0, private delayValueTrigger?: T) {
this.isActive = true;
}
@@ -20,8 +44,21 @@ export class DataBinding<T> {
public set Value(value: T) {
if (value !== this.value) {
this.value = value;
this.valueChanged.fire(this.value);
if (this.delay === 0 || value !== this.delayValueTrigger) {
this.value = value;
this.valueChanged.fire(this.value);
} else {
if (this.deferral) {
this.deferral.cancel();
}
this.deferral = new Deferral(() => {
this.value = value;
this.valueChanged.fire(this.value);
}, this.delay);
}
} else if (this.deferral) {
this.deferral.cancel();
this.deferral = undefined;
}
}
+9 -29
View File
@@ -46,9 +46,6 @@ const commandArguments: string[] = []; // We report the sender of the command
export class LanguageStatusUI {
private currentClient: Client | undefined;
// Timer for icons from appearing too often and for too short of a time.
private readonly iconDelayTime: number = 1000;
// IntelliSense language status
private intelliSenseStatusItem: vscode.LanguageStatusItem;
private readonly updatingIntelliSenseText: string = localize("updating.intellisense.text", "IntelliSense: Updating");
@@ -58,7 +55,6 @@ export class LanguageStatusUI {
private isParsingWorkspace: boolean = false;
private isParsingWorkspacePaused: boolean = false;
private isParsingFiles: boolean = false;
private tagParseTimeout?: NodeJS.Timeout;
private readonly dataBaseIcon: string = "$(database)";
private readonly workspaceParsingInitializing: string = localize("initializing.tagparser.text", "Initializing Workspace");
private readonly workspaceParsingIndexing: string = localize("indexing.tagparser.text", "Indexing Workspace");
@@ -115,25 +111,15 @@ export class LanguageStatusUI {
return item;
}
private flameTimeout?: NodeJS.Timeout;
private setIsUpdatingIntelliSense(val: boolean): void {
this.intelliSenseStatusItem.busy = val;
if (this.flameTimeout) {
clearTimeout(this.flameTimeout);
}
if (val) {
this.intelliSenseStatusItem.text = "$(flame)";
this.intelliSenseStatusItem.detail = this.updatingIntelliSenseText;
this.flameTimeout = undefined;
} else {
this.flameTimeout = setTimeout(() => {
if (this.intelliSenseStatusItem) {
this.intelliSenseStatusItem.text = this.idleIntelliSenseText;
this.intelliSenseStatusItem.detail = "";
}
}, this.iconDelayTime);
this.intelliSenseStatusItem.text = this.idleIntelliSenseText;
this.intelliSenseStatusItem.detail = "";
}
this.intelliSenseStatusItem.command = {
command: "C_Cpp.RestartIntelliSenseForFile",
@@ -220,10 +206,6 @@ export class LanguageStatusUI {
private setTagParseStatus(): void {
// Set busy icon outside of timer for more real-time response
this.tagParseStatusItem.busy = (this.isParsingWorkspace && !this.isParsingWorkspacePaused) || this.isParsingFiles;
if (this.tagParseStatusItem.busy && this.tagParseTimeout) {
clearTimeout(this.tagParseTimeout);
this.tagParseTimeout = undefined;
}
if (this.isParsingWorkspace || this.isParsingFiles) {
this.tagParseStatusItem.text = this.dataBaseIcon;
@@ -251,15 +233,13 @@ export class LanguageStatusUI {
}
} else {
// Parsing completed.
this.tagParseTimeout = setTimeout(() => {
this.tagParseStatusItem.text = this.workspaceParsingDoneText;
this.tagParseStatusItem.detail = "";
this.tagParseStatusItem.command = {
command: "C_Cpp.RescanWorkspace",
title: this.workspaceRescanText,
arguments: commandArguments
};
}, this.iconDelayTime);
this.tagParseStatusItem.text = this.workspaceParsingDoneText;
this.tagParseStatusItem.detail = "";
this.tagParseStatusItem.command = {
command: "C_Cpp.RescanWorkspace",
title: this.workspaceRescanText,
arguments: commandArguments
};
}
}
//#endregion Tag parse language status