Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Features:

- Add an option to specify the launch target for debugging CTest tests. [#4273](https://github.com/microsoft/vscode-cmake-tools/pull/4273)
- Add a setting to enable/disable our built-in language services. [#4290](https://github.com/microsoft/vscode-cmake-tools/issues/4290)

Improvements:

Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3624,6 +3624,12 @@
"description": "%cmake-tools.configuration.cmake.enableAutomaticKitScan.description%",
"scope": "resource"
},
"cmake.enableLanguageServices": {
"type": "boolean",
"default": true,
"description": "%cmake-tools.configuration.cmake.enableLanguageServices.description%",
"scope": "machine"
},
"cmake.preRunCoverageTarget": {
"type": "string",
"default": null,
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
]
},
"cmake-tools.configuration.cmake.enableAutomaticKitScan.description": "Enable automatic scanning for kits when a kit isn't selected. This will only take affect when CMake Presets aren't being used.",
"cmake-tools.configuration.cmake.enableLanguageServices.description": "Enable language services for CMake files. This will enable syntax highlighting, code completion, and other features.",
"cmake-tools.configuration.cmake.preRunCoverageTarget.description": "Target to build before running tests with coverage using the test explorer",
"cmake-tools.configuration.cmake.postRunCoverageTarget.description": "Target to build after running tests with coverage using the test explorer",
"cmake-tools.configuration.cmake.coverageInfoFiles.description": "LCOV coverage info files to be processed after running tests with coverage using the test explorer.",
Expand Down
6 changes: 6 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ export interface ExtensionConfigurationSettings {
automaticReconfigure: boolean;
pinnedCommands: string[];
enableAutomaticKitScan: boolean;
enableLanguageServices: boolean;
preRunCoverageTarget: string | null;
postRunCoverageTarget: string | null;
coverageInfoFiles: string[];
Expand Down Expand Up @@ -571,6 +572,10 @@ export class ConfigurationReader implements vscode.Disposable {
return this.configData.enableAutomaticKitScan;
}

get enableLanguageServices(): boolean {
return this.configData.enableLanguageServices;
}

get preRunCoverageTarget(): string | null {
return this.configData.preRunCoverageTarget;
}
Expand Down Expand Up @@ -648,6 +653,7 @@ export class ConfigurationReader implements vscode.Disposable {
automaticReconfigure: new vscode.EventEmitter<boolean>(),
pinnedCommands: new vscode.EventEmitter<string[]>(),
enableAutomaticKitScan: new vscode.EventEmitter<boolean>(),
enableLanguageServices: new vscode.EventEmitter<boolean>(),
preRunCoverageTarget: new vscode.EventEmitter<string | null>(),
postRunCoverageTarget: new vscode.EventEmitter<string | null>(),
coverageInfoFiles: new vscode.EventEmitter<string[]>()
Expand Down
146 changes: 98 additions & 48 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ export class ExtensionManager implements vscode.Disposable {
private onDidChangeActiveTextEditorSub: vscode.Disposable = new DummyDisposable();
private readonly extensionActiveCommandsEmitter = new vscode.EventEmitter<void>();
private readonly workspaceConfig: ConfigurationReader = ConfigurationReader.create();
private readonly CMAKE_LANGUAGE = "cmake";
private readonly CMAKE_SELECTOR: vscode.DocumentSelector = [
{ language: this.CMAKE_LANGUAGE, scheme: "file" },
{ language: this.CMAKE_LANGUAGE, scheme: "untitled" }
];
private languageServicesDisposables: vscode.Disposable[] = [];

private updateTouchBarVisibility(config: TouchBarConfig) {
const touchBarVisible = config.visibility === "default";
Expand All @@ -119,6 +125,17 @@ export class ExtensionManager implements vscode.Disposable {
* Second-phase async init
*/
public async init() {
if (this.workspaceConfig.enableLanguageServices) {
await this.enableLanguageServices();
this.workspaceConfig.onChange('enableLanguageServices', async (value) => {
if (value) {
await this.enableLanguageServices();
} else {
this.disposeLanguageServices();
}
});
}

this.updateTouchBarVisibility(this.workspaceConfig.touchbar);
this.workspaceConfig.onChange('touchbar', config => this.updateTouchBarVisibility(config));

Expand Down Expand Up @@ -357,6 +374,7 @@ export class ExtensionManager implements vscode.Disposable {
private activeTestPresetSub: vscode.Disposable = new DummyDisposable();
private activePackagePresetSub: vscode.Disposable = new DummyDisposable();
private activeWorkflowPresetSub: vscode.Disposable = new DummyDisposable();
private enableLanguageServicesSub: vscode.Disposable = new DummyDisposable();

// Watch the code model so that we may update the tree view
// <fspath, sub>
Expand All @@ -379,6 +397,83 @@ export class ExtensionManager implements vscode.Disposable {
private cppToolsAPI?: cpt.CppToolsApi;
private configProviderRegistered?: boolean = false;

private async enableLanguageServices() {
try {
const languageServices = await LanguageServiceData.create();
this.languageServicesDisposables.push(vscode.languages.registerHoverProvider(
this.CMAKE_SELECTOR,
languageServices
));
this.languageServicesDisposables.push(vscode.languages.registerCompletionItemProvider(
this.CMAKE_SELECTOR,
languageServices
));
} catch {
log.error(
localize(
"language.service.failed",
"Failed to initialize language services"
)
);
}

this.languageServicesDisposables.push(vscode.languages.setLanguageConfiguration(
this.CMAKE_LANGUAGE,
{
indentationRules: {
// ^(.*\*/)?\s*\}.*$
decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/,
// ^.*\{[^}"']*$
increaseIndentPattern: /^.*\{[^}"']*$/
},
wordPattern:
/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
comments: {
lineComment: "#"
},
brackets: [
["{", "}"],
["(", ")"]
],

__electricCharacterSupport: {
brackets: [
{
tokenType: "delimiter.curly.ts",
open: "{",
close: "}",
isElectric: true
},
{
tokenType: "delimiter.square.ts",
open: "[",
close: "]",
isElectric: true
},
{
tokenType: "delimiter.paren.ts",
open: "(",
close: ")",
isElectric: true
}
]
},

__characterPairSupport: {
autoClosingPairs: [
{ open: "{", close: "}" },
{ open: "(", close: ")" },
{ open: '"', close: '"', notIn: ["string"] }
]
}
}
));
}

private disposeLanguageServices() {
this.languageServicesDisposables.forEach(sub => sub.dispose());
}

private getProjectsForWorkspaceFolder(folder?: vscode.WorkspaceFolder): CMakeProject[] | undefined {
folder = this.getWorkspaceFolder(folder);
return this.projectController.getProjectsForWorkspaceFolder(folder);
Expand Down Expand Up @@ -554,6 +649,7 @@ export class ExtensionManager implements vscode.Disposable {
*/
async asyncDispose() {
this.disposeSubs();
this.disposeLanguageServices();
this.codeModelUpdateSubs.forEach(
subs => subs.forEach(
sub => sub.dispose()
Expand Down Expand Up @@ -736,7 +832,7 @@ export class ExtensionManager implements vscode.Disposable {

private disposeSubs() {
util.disposeAll(this.projectSubscriptions);
for (const sub of [this.statusMessageSub, this.targetNameSub, this.buildTypeSub, this.launchTargetSub, this.ctestEnabledSub, this.isBusySub, this.activeConfigurePresetSub, this.activeBuildPresetSub, this.activeTestPresetSub, this.activePackagePresetSub, this.activeWorkflowPresetSub]) {
for (const sub of [this.statusMessageSub, this.targetNameSub, this.buildTypeSub, this.launchTargetSub, this.ctestEnabledSub, this.isBusySub, this.activeConfigurePresetSub, this.activeBuildPresetSub, this.activeTestPresetSub, this.activePackagePresetSub, this.activeWorkflowPresetSub, this.enableLanguageServicesSub]) {
sub.dispose();
}
}
Expand Down Expand Up @@ -834,6 +930,7 @@ export class ExtensionManager implements vscode.Disposable {
this.activeTestPresetSub = new DummyDisposable();
this.activePackagePresetSub = new DummyDisposable();
this.activeWorkflowPresetSub = new DummyDisposable();
this.enableLanguageServicesSub = new DummyDisposable();
this.statusBar.setActiveKitName('');
this.statusBar.setConfigurePresetName('');
this.statusBar.setBuildPresetName('');
Expand Down Expand Up @@ -2400,53 +2497,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<api.CM
});
}

const CMAKE_LANGUAGE = "cmake";
const CMAKE_SELECTOR: vscode.DocumentSelector = [
{ language: CMAKE_LANGUAGE, scheme: 'file'},
{ language: CMAKE_LANGUAGE, scheme: 'untitled'}
];

try {
const languageServices = await LanguageServiceData.create();
vscode.languages.registerHoverProvider(CMAKE_SELECTOR, languageServices);
vscode.languages.registerCompletionItemProvider(CMAKE_SELECTOR, languageServices);
} catch {
log.error(localize('language.service.failed', 'Failed to initialize language services'));
}

vscode.languages.setLanguageConfiguration(CMAKE_LANGUAGE, {
indentationRules: {
// ^(.*\*/)?\s*\}.*$
decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/,
// ^.*\{[^}"']*$
increaseIndentPattern: /^.*\{[^}"']*$/
},
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
comments: {
lineComment: '#'
},
brackets: [
['{', '}'],
['(', ')']
],

__electricCharacterSupport: {
brackets: [
{ tokenType: 'delimiter.curly.ts', open: '{', close: '}', isElectric: true },
{ tokenType: 'delimiter.square.ts', open: '[', close: ']', isElectric: true },
{ tokenType: 'delimiter.paren.ts', open: '(', close: ')', isElectric: true }
]
},

__characterPairSupport: {
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] }
]
}
});

if (vscode.workspace.getConfiguration('cmake').get('showOptionsMovedNotification')) {
void vscode.window.showInformationMessage(
localize('options.moved.notification.body', "Some status bar options in CMake Tools have now moved to the Project Status View in the CMake Tools sidebar. You can customize your view with the 'cmake.options' property in settings."),
Expand Down
1 change: 1 addition & 0 deletions test/unit-tests/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ function createConfig(conf: Partial<ExtensionConfigurationSettings>): Configurat
ignoreCMakeListsMissing: false,
automaticReconfigure: false,
enableAutomaticKitScan: true,
enableLanguageServices: true,
preRunCoverageTarget: null,
postRunCoverageTarget: null,
coverageInfoFiles: []
Expand Down