in src/cmake-tools.ts [861:976]
private async _init() {
log.debug(localize('second.phase.init', 'Starting CMakeTools second-phase init'));
this._sourceDir = await util.normalizeAndVerifySourceDir(
await expandString(this.workspaceContext.config.sourceDirectory, CMakeDriver.sourceDirExpansionOptions(this.folder.uri.fsPath))
);
// Start up the variant manager
await this._variantManager.initialize();
// Set the status bar message
this._activeVariant.set(this._variantManager.activeVariantOptions.short);
// Restore the debug target
this._launchTargetName.set(this.workspaceContext.state.launchTargetName || '');
// Hook up event handlers
// Listen for the variant to change
this._variantManager.onActiveVariantChanged(() => {
log.debug(localize('active.build.variant.changed', 'Active build variant changed'));
rollbar.invokeAsync(localize('changing.build.variant', 'Changing build variant'), async () => {
const drv = await this.getCMakeDriverInstance();
if (drv) {
await drv.setVariant(this._variantManager.activeVariantOptions, this._variantManager.activeKeywordSetting);
this._activeVariant.set(this._variantManager.activeVariantOptions.short);
// We don't configure yet, since someone else might be in the middle of a configure
}
});
});
this._ctestController.onTestingEnabledChanged(enabled => this._ctestEnabled.set(enabled));
this._ctestController.onResultsChanged(res => this._testResults.set(res));
this._statusMessage.set(localize('ready.status', 'Ready'));
this.extensionContext.subscriptions.push(vscode.workspace.onDidOpenTextDocument(async td => {
const str = td.uri.fsPath.toLowerCase();
if (str.endsWith("cmakelists.txt") || str.endsWith(".cmake")) {
telemetry.logEvent("cmakeFileOpen");
}
}));
this.extensionContext.subscriptions.push(vscode.workspace.onDidSaveTextDocument(async td => {
const str = td.uri.fsPath.toLowerCase();
const drv = await this.getCMakeDriverInstance();
// If we detect a change in the CMake cache file, refresh the webview
if (this._cacheEditorWebview && drv && lightNormalizePath(str) === drv.cachePath.toLowerCase()) {
await this._cacheEditorWebview.refreshPanel();
}
const sourceDirectory = (this.sourceDir).toLowerCase();
let isCmakeListsFile: boolean = false;
if (str.endsWith("cmakelists.txt")) {
const allcmakelists: string[] | undefined = await util.getAllCMakeListsPaths(this.folder.uri);
// Look for the CMakeLists.txt files that are in the workspace or the sourceDirectory root.
isCmakeListsFile = (str === path.join(sourceDirectory, "cmakelists.txt")) ||
(allcmakelists?.find(file => str === file.toLocaleLowerCase()) !== undefined);
}
if (isCmakeListsFile) {
// CMakeLists.txt change event: its creation or deletion are relevant,
// so update full/partial feature set view for this folder.
await updateFullFeatureSetForFolder(this.folder);
if (drv && !drv.configOrBuildInProgress()) {
if (drv.config.configureOnEdit) {
log.debug(localize('cmakelists.save.trigger.reconfigure', "Detected saving of CMakeLists.txt, attempting automatic reconfigure..."));
await this.configureInternal(ConfigureTrigger.cmakeListsChange, [], ConfigureType.Normal);
}
} else {
log.warning(localize('cmakelists.save.could.not.reconfigure',
'Changes were detected in CMakeLists.txt but we could not reconfigure the project because another operation is already in progress.'));
log.debug(localize('needs.reconfigure', 'The project needs to be reconfigured so that the changes saved in CMakeLists.txt have effect.'));
}
}
// For multi-root, the "onDidSaveTextDocument" will be received once for each project folder.
// To avoid misleading telemetry, consider the notification only for the active folder.
// There is always one active folder in a workspace and never more than one.
if (isActiveFolder(this.folder)) {
// "outside" evaluates whether the modified cmake file belongs to the active folder.
// Currently, we don't differentiate between outside active folder but inside any of the other
// workspace folders versus outside any folder referenced by the current workspace.
let outside: boolean = true;
let fileType: string | undefined;
if (str.endsWith("cmakelists.txt")) {
fileType = "CMakeLists";
// The CMakeLists.txt belongs to the current active folder only if sourceDirectory points to it.
if (str === path.join(sourceDirectory, "cmakelists.txt")) {
outside = false;
}
} else if (str.endsWith("cmakecache.txt")) {
fileType = "CMakeCache";
const binaryDirectory = (await this.binaryDir).toLowerCase();
// The CMakeCache.txt belongs to the current active folder only if binaryDirectory points to it.
if (str === path.join(binaryDirectory, "cmakecache.txt")) {
outside = false;
}
} else if (str.endsWith(".cmake")) {
fileType = ".cmake";
const binaryDirectory = (await this.binaryDir).toLowerCase();
// Instead of parsing how and from where a *.cmake file is included or imported
// let's consider one inside the active folder if it's in the workspace folder,
// sourceDirectory or binaryDirectory.
if (str.startsWith(this.folder.uri.fsPath.toLowerCase()) ||
str.startsWith(sourceDirectory) ||
str.startsWith(binaryDirectory)) {
outside = false;
}
}
if (fileType) {
telemetry.logEvent("cmakeFileWrite", { filetype: fileType, outsideActiveFolder: outside.toString() });
}
}
}));
}