New settings: build before launch, save before debug, clear output channel (#91)

* New settings: build before launch, save before debug, clear output channel.

* Remove unused import

* PR feedback
This commit is contained in:
Andreea Isac 2021-02-04 09:29:27 -08:00 коммит произвёл GitHub
Родитель fbf27b7fbc
Коммит 92143cfaab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 146 добавлений и 8 удалений

Просмотреть файл

@ -417,12 +417,30 @@
"scope": "resource" "scope": "resource"
}, },
"makefile.phonyOnlyTargets": { "makefile.phonyOnlyTargets": {
"type": "boolean", "type": "boolean",
"default": false, "default": false,
"description": "Display only the phony targets", "description": "Display only the phony targets",
"scope": "resource" "scope": "resource"
} },
} "makefile.saveBeforeBuildOrConfigure": {
"type": "boolean",
"default": true,
"description": "Save opened files before building or configuring",
"scope": "resource"
},
"makefile.buildBeforeLaunch": {
"type": "boolean",
"default": true,
"description": "Build the current target before launch (debug/run)",
"scope": "resource"
},
"makefile.clearOutputBeforeBuild": {
"type": "boolean",
"default": true,
"description": "Clear the output channel at the beginning of a build",
"scope": "resource"
}
}
}, },
"viewsContainers": { "viewsContainers": {
"activitybar": [ "activitybar": [

Просмотреть файл

@ -718,6 +718,33 @@ export function readPhonyOnlyTargets(): void {
logger.message(`Only .PHONY targets: ${phonyOnlyTargets}`); logger.message(`Only .PHONY targets: ${phonyOnlyTargets}`);
} }
let saveBeforeBuildOrConfigure: boolean | undefined;
export function getSaveBeforeBuildOrConfigure(): boolean | undefined { return saveBeforeBuildOrConfigure; }
export function setSaveBeforeBuildOrConfigure(save: boolean): void { saveBeforeBuildOrConfigure = save; }
export function readSaveBeforeBuildOrConfigure(): void {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("makefile");
saveBeforeBuildOrConfigure = workspaceConfiguration.get<boolean>("saveBeforeBuildOrConfigure");
logger.message(`Save before build or configure: ${saveBeforeBuildOrConfigure}`);
}
let buildBeforeLaunch: boolean | undefined;
export function getBuildBeforeLaunch(): boolean | undefined { return buildBeforeLaunch; }
export function setBuildBeforeLaunch(build: boolean): void { buildBeforeLaunch = build; }
export function readBuildBeforeLaunch(): void {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("makefile");
buildBeforeLaunch = workspaceConfiguration.get<boolean>("buildBeforeLaunch");
logger.message(`Build before launch: ${buildBeforeLaunch}`);
}
let clearOutputBeforeBuild: boolean | undefined;
export function getClearOutputBeforeBuild(): boolean | undefined { return clearOutputBeforeBuild; }
export function setClearOutputBeforeBuild(clear: boolean): void { clearOutputBeforeBuild = clear; }
export function readClearOutputBeforeBuild(): void {
let workspaceConfiguration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("makefile");
clearOutputBeforeBuild = workspaceConfiguration.get<boolean>("clearOutputBeforeBuild");
logger.message(`Clear output before build: ${clearOutputBeforeBuild}`);
}
// This setting is useful for some repos where directory changing commands (cd, push, pop) // This setting is useful for some repos where directory changing commands (cd, push, pop)
// are missing or printed more than once, resulting in associating some IntelliSense information // are missing or printed more than once, resulting in associating some IntelliSense information
// with the wrong file or even with a non existent URL. // with the wrong file or even with a non existent URL.
@ -754,6 +781,9 @@ export async function initFromStateAndSettings(): Promise<void> {
readConfigureOnEdit(); readConfigureOnEdit();
readConfigureAfterCommand(); readConfigureAfterCommand();
readPhonyOnlyTargets(); readPhonyOnlyTargets();
readSaveBeforeBuildOrConfigure();
readBuildBeforeLaunch();
readClearOutputBeforeBuild();
readIgnoreDirectoryCommands(); readIgnoreDirectoryCommands();
analyzeConfigureParams(); analyzeConfigureParams();
@ -1052,6 +1082,27 @@ export async function initFromStateAndSettings(): Promise<void> {
updatedSettingsSubkeys.push(subKey); updatedSettingsSubkeys.push(subKey);
} }
subKey = "saveBeforeBuildOrConfigure";
let updatedSaveBeforeBuildOrConfigure : boolean | undefined = workspaceConfiguration.get<boolean>(subKey);
if (updatedSaveBeforeBuildOrConfigure !== saveBeforeBuildOrConfigure) {
readSaveBeforeBuildOrConfigure();
updatedSettingsSubkeys.push(subKey);
}
subKey = "buildBeforeLaunch";
let updatedBuildBeforeLaunch : boolean | undefined = workspaceConfiguration.get<boolean>(subKey);
if (updatedBuildBeforeLaunch !== buildBeforeLaunch) {
readBuildBeforeLaunch();
updatedSettingsSubkeys.push(subKey);
}
subKey = "clearOutputBeforeBuild";
let updatedClearOutputBeforeBuild : boolean | undefined = workspaceConfiguration.get<boolean>(subKey);
if (updatedClearOutputBeforeBuild !== clearOutputBeforeBuild) {
readClearOutputBeforeBuild();
updatedSettingsSubkeys.push(subKey);
}
subKey = "ignoreDirectoryCommands"; subKey = "ignoreDirectoryCommands";
let updatedIgnoreDirectoryCommands : boolean | undefined = workspaceConfiguration.get<boolean>(subKey); let updatedIgnoreDirectoryCommands : boolean | undefined = workspaceConfiguration.get<boolean>(subKey);
if (updatedIgnoreDirectoryCommands !== ignoreDirectoryCommands) { if (updatedIgnoreDirectoryCommands !== ignoreDirectoryCommands) {

Просмотреть файл

@ -16,7 +16,8 @@ export enum LaunchStatuses {
success = "success", success = "success",
blocked = "blocked by (pre)configure or build", blocked = "blocked by (pre)configure or build",
noLaunchConfigurationSet = "no launch configuration set by the user", noLaunchConfigurationSet = "no launch configuration set by the user",
launchTargetsListEmpty = "launch targets list empty" launchTargetsListEmpty = "launch targets list empty",
buildFailed = "build failed",
} }
let launcher: Launcher; let launcher: Launcher;
@ -185,6 +186,30 @@ export class Launcher implements vscode.Disposable {
return LaunchStatuses.blocked; return LaunchStatuses.blocked;
} }
if (configuration.getBuildBeforeLaunch()) {
let currentBuildTarget: string = configuration.getCurrentTarget() || "";
logger.message(`Building current target before launch: "${currentBuildTarget}"`);
let buildSuccess: boolean = (await make.buildTarget(make.TriggeredBy.buildTarget, currentBuildTarget, false)) === make.ConfigureBuildReturnCodeTypes.success;
if (!buildSuccess) {
logger.message(`Building target "${currentBuildTarget}" failed.`);
let noButton: string = "No";
let yesButton: string = "Yes";
const chosen: vscode.MessageItem | undefined = await vscode.window.showErrorMessage<vscode.MessageItem>("Build failed. Do you want to continue anyway?",
{
title: yesButton,
isCloseAffordance: false,
},
{
title: noButton,
isCloseAffordance: true
});
if (chosen === undefined || chosen.title === noButton) {
return LaunchStatuses.buildFailed;
}
}
}
let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration(); let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
if (!currentLaunchConfiguration) { if (!currentLaunchConfiguration) {
// If no launch configuration is set, give the user a chance to select one now from the quick pick // If no launch configuration is set, give the user a chance to select one now from the quick pick

Просмотреть файл

@ -38,6 +38,12 @@ export function showOutputChannel(): void {
} }
} }
export function clearOutputChannel(): void {
if (makeOutputChannel) {
makeOutputChannel.clear();
}
}
//TODO: implement more verbosity levels for the output log //TODO: implement more verbosity levels for the output log
export function message(message: string, loggingLevel?: string): void { export function message(message: string, loggingLevel?: string): void {
// Print the message only if the intended logging level matches the settings // Print the message only if the intended logging level matches the settings

Просмотреть файл

@ -44,7 +44,8 @@ export enum ConfigureBuildReturnCodeTypes {
cancelled = -2, cancelled = -2,
notFound = -3, notFound = -3,
outOfDate = -4, outOfDate = -4,
other = -5 other = -5,
saveFailed = -6,
} }
export enum Operations { export enum Operations {
@ -75,6 +76,7 @@ export enum TriggeredBy {
configureBeforeTargetChange = "configure dirty (before target change), settings (configureAfterCommand)", configureBeforeTargetChange = "configure dirty (before target change), settings (configureAfterCommand)",
configureAfterTargetChange = "settings (configureAfterCommand), command pallette (setBuildTarget)", configureAfterTargetChange = "settings (configureAfterCommand), command pallette (setBuildTarget)",
configureBeforeLaunchTargetChange = "configureDirty (before launch target change), settings (configureAfterCommand)", configureBeforeLaunchTargetChange = "configureDirty (before launch target change), settings (configureAfterCommand)",
launch = "Launch (debug/run)",
} }
let fileIndex: Map<string, cpp.SourceFileConfigurationItem> = new Map<string, cpp.SourceFileConfigurationItem>(); let fileIndex: Map<string, cpp.SourceFileConfigurationItem> = new Map<string, cpp.SourceFileConfigurationItem>();
@ -129,6 +131,33 @@ export function blockedByOp(op: Operations, showPopup: boolean = true): Operatio
return blocker; return blocker;
} }
async function saveAll(): Promise<boolean> {
if (configuration.getSaveBeforeBuildOrConfigure()) {
logger.message("Saving opened files before build.");
let saveSuccess: boolean = await vscode.workspace.saveAll();
if (saveSuccess) {
return true;
} else {
logger.message("Saving opened files failed.");
let yesButton: string = "Yes";
let noButton: string = "No";
const chosen: vscode.MessageItem | undefined = await vscode.window.showErrorMessage<vscode.MessageItem>("Saving opened files failed. Do you want to continue anyway?",
{
title: yesButton,
isCloseAffordance: false,
},
{
title: noButton,
isCloseAffordance: true
});
return chosen !== undefined && chosen.title === yesButton;
}
} else {
return true;
}
}
export function prepareBuildTarget(target: string, clean: boolean = false): string[] { export function prepareBuildTarget(target: string, clean: boolean = false): string[] {
let makeArgs: string[] = []; let makeArgs: string[] = [];
// Prepend the target to the arguments given in the configurations json. // Prepend the target to the arguments given in the configurations json.
@ -170,7 +199,12 @@ export async function buildTarget(triggeredBy: TriggeredBy, target: string, clea
return ConfigureBuildReturnCodeTypes.blocked; return ConfigureBuildReturnCodeTypes.blocked;
} }
if (!saveAll()) {
return ConfigureBuildReturnCodeTypes.saveFailed;
}
logger.showOutputChannel(); logger.showOutputChannel();
logger.clearOutputChannel();
// Same start time for build and an eventual configure. // Same start time for build and an eventual configure.
let buildStartTime: number = Date.now(); let buildStartTime: number = Date.now();
@ -773,6 +807,10 @@ export async function configure(triggeredBy: TriggeredBy, updateTargets: boolean
return ConfigureBuildReturnCodeTypes.blocked; return ConfigureBuildReturnCodeTypes.blocked;
} }
if (!saveAll()) {
return ConfigureBuildReturnCodeTypes.saveFailed;
}
logger.showOutputChannel(); logger.showOutputChannel();
// Same start time for configure and an eventual pre-configure. // Same start time for configure and an eventual pre-configure.