CMake the way CLion does it (profiles and presets, targets, run and debug configurations, CTest) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Tomáš Černík <Tom.cernik@gmail.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
1 parent
f8032fd65d
commit
093cf7ee9c
38 files changed
+9352
No files matched your search
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* CLion's toolbar in the status bar: the profile, the target (or a GDB server
|
||||
* configuration), then Build, Run and Debug for it; and a "Reload" when a CMake file changed.
|
||||
*/
|
||||
import * as vscode from "vscode";
|
||||
import { KINDS } from "./gdbConfigs";
|
||||
import { programOf } from "./launcher";
|
||||
import type { CMakeProject } from "./project";
|
||||
import { settings } from "./util";
|
||||
|
||||
export class StatusBar implements vscode.Disposable {
|
||||
private readonly reload = vscode.window.createStatusBarItem("cmakeHelper.reload", vscode.StatusBarAlignment.Left, 104);
|
||||
private readonly profile = vscode.window.createStatusBarItem("cmakeHelper.profile", vscode.StatusBarAlignment.Left, 103);
|
||||
private readonly target = vscode.window.createStatusBarItem("cmakeHelper.target", vscode.StatusBarAlignment.Left, 102);
|
||||
private readonly build = vscode.window.createStatusBarItem("cmakeHelper.build", vscode.StatusBarAlignment.Left, 101.3);
|
||||
private readonly run = vscode.window.createStatusBarItem("cmakeHelper.run", vscode.StatusBarAlignment.Left, 101.2);
|
||||
private readonly debug = vscode.window.createStatusBarItem("cmakeHelper.debug", vscode.StatusBarAlignment.Left, 101.1);
|
||||
|
||||
constructor() {
|
||||
this.reload.name = "CMake: Reload";
|
||||
this.profile.name = "CMake: Profile";
|
||||
this.target.name = "CMake: Target";
|
||||
this.build.name = "CMake: Build";
|
||||
this.run.name = "CMake: Run";
|
||||
this.debug.name = "CMake: Debug";
|
||||
this.profile.command = "cmakeHelper.selectProfile";
|
||||
this.target.command = "cmakeHelper.selectTarget";
|
||||
this.build.command = "cmakeHelper.build";
|
||||
this.run.command = "cmakeHelper.run";
|
||||
this.debug.command = "cmakeHelper.debug";
|
||||
this.build.text = "$(tools)";
|
||||
this.run.text = "$(play)";
|
||||
this.debug.text = "$(debug-alt)";
|
||||
}
|
||||
|
||||
update(p: CMakeProject | undefined): void {
|
||||
this.show(p);
|
||||
// Build, Run and Debug are the editors' buttons then (package.json's editor/title).
|
||||
if (settings().get<string>("toolbar") === "editorTitle") [this.build, this.run, this.debug].forEach((i) => i.hide());
|
||||
}
|
||||
|
||||
private show(p: CMakeProject | undefined): void {
|
||||
const all = [this.reload, this.profile, this.target, this.build, this.run, this.debug];
|
||||
if (!p) {
|
||||
all.forEach((i) => i.hide());
|
||||
return;
|
||||
}
|
||||
if (p.state === "configuring") {
|
||||
this.reload.text = "$(sync~spin) CMake";
|
||||
this.reload.tooltip = "Loading the CMake project… (click to stop)";
|
||||
this.reload.command = "cmakeHelper.cancelReload";
|
||||
this.reload.backgroundColor = undefined;
|
||||
this.reload.show();
|
||||
} else if (p.needsReload || !p.model) {
|
||||
this.reload.text = p.model ? "$(refresh) Reload CMake" : "$(warning) Load CMake";
|
||||
this.reload.tooltip = p.model ? "CMake files changed since the project was loaded" : "The CMake project isn't loaded";
|
||||
this.reload.command = "cmakeHelper.reload";
|
||||
this.reload.backgroundColor = new vscode.ThemeColor("statusBarItem.warningBackground");
|
||||
this.reload.show();
|
||||
} else {
|
||||
this.reload.hide();
|
||||
}
|
||||
|
||||
this.profile.text = `$(layers) ${p.activeProfile.name}`;
|
||||
this.profile.tooltip = `CMake profile: ${p.activeProfile.name} (${p.activeProfile.buildType})\n${p.activeProfile.buildDir}`;
|
||||
this.profile.show();
|
||||
|
||||
const busy = p.state !== "idle";
|
||||
const gdb = p.activeGdbConfiguration;
|
||||
if (p.model && gdb) {
|
||||
// A GDB server configuration in place of a target, as CLion's run configuration.
|
||||
const target = gdb.target ?? p.activeTarget?.name;
|
||||
this.target.text = `$(${gdb.kind === "embedded" ? "chip" : "remote"}) ${gdb.name}`;
|
||||
this.target.tooltip = `${KINDS[gdb.kind]}: ${gdb.name}${target ? ` (${target})` : ""}\nClick to choose another target or configuration`;
|
||||
this.target.show();
|
||||
this.build.tooltip = busy ? "Busy…" : `Build ${target ?? ""} (Ctrl+F9)`;
|
||||
this.build.text = p.state === "building" ? "$(loading~spin)" : "$(tools)";
|
||||
this.build.show();
|
||||
if (gdb.kind === "embedded" || gdb.ssh) {
|
||||
this.run.tooltip = gdb.kind === "embedded" ? `Download & Run ${gdb.name} (Shift+F10)` : `Run ${gdb.name} on ${gdb.ssh} (Shift+F10)`;
|
||||
this.run.show();
|
||||
} else {
|
||||
this.run.hide();
|
||||
}
|
||||
this.debug.tooltip = `Debug ${gdb.name} (Shift+F9)`;
|
||||
this.debug.show();
|
||||
return;
|
||||
}
|
||||
|
||||
const t = p.activeTarget;
|
||||
if (!p.model || !t) {
|
||||
[this.target, this.build, this.run, this.debug].forEach((i) => i.hide());
|
||||
return;
|
||||
}
|
||||
this.target.text = `$(target) ${t.name}`;
|
||||
this.target.tooltip = "Target to build, run and debug";
|
||||
this.target.show();
|
||||
this.build.tooltip = busy ? "Busy…" : `Build ${t.name} (Ctrl+F9)`;
|
||||
this.build.text = p.state === "building" ? "$(loading~spin)" : "$(tools)";
|
||||
this.build.show();
|
||||
// ▶ for what has a program to run, and for a custom target (it's built); 🐞 for those too.
|
||||
const program = !!programOf(p, t);
|
||||
this.run.tooltip = program ? `Run ${t.name} (Shift+F10)` : `Build ${t.name}: it runs no program (Shift+F10)`;
|
||||
// A custom target's 🐞 debugs the program its command runs.
|
||||
this.debug.tooltip = program || t.type !== "UTILITY" ? `Debug ${t.name} (Shift+F9)` : `Debug the program ${t.name}'s command runs (Shift+F9)`;
|
||||
if (program || t.type === "UTILITY") this.run.show();
|
||||
else this.run.hide();
|
||||
if (program || t.type === "UTILITY") this.debug.show();
|
||||
else this.debug.hide();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
[this.reload, this.profile, this.target, this.build, this.run, this.debug].forEach((i) => i.dispose());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user