| name | add-command |
| description | Use when adding a new cmake.* command to CMake Tools. Touches package.json (contributes.commands), package.nls.json, src/extension.ts (funs array), and CHANGELOG.md. Triggers: "add command", "register command", "new command palette entry".
|
Adding a New Command
Recipe for adding a new cmake.* command to CMake Tools.
Files you must touch
| File | What to add |
|---|
package.json | Command declaration in contributes.commands + optional menu entries |
package.nls.json | English title string |
src/extension.ts | Method name in funs array + handler method on ExtensionManager |
CHANGELOG.md | Entry under the current version |
Step 1 — Declare the command in package.json
1a — contributes.commands
{
"command": "cmake.myCommand",
"title": "%cmake-tools.command.cmake.myCommand.title%",
"category": "CMake"
}
Rules
- Command ID format:
cmake.<commandName> (camelCase).
- Title: NLS key in the format
%cmake-tools.command.cmake.<commandName>.title%.
- Category:
"CMake" — this prefixes the title in the Command Palette as CMake: <title>.
when (optional): controls when the command appears in the Command Palette.
icon (optional): Codicon reference like "$(settings-gear)" for tree-view inline buttons.
1b — contributes.menus (if needed)
Add visibility rules for where the command appears.
Command Palette visibility:
{
"command": "cmake.myCommand",
"when": "cmake:enableFullFeatureSet"
}
Sidebar tree-view inline button:
{
"command": "cmake.projectStatus.myCommand",
"when": "view == cmake.projectStatus && cmake:enableFullFeatureSet && viewItem == 'myItem'",
"group": "inline"
}
Common when clause patterns:
| Pattern | Meaning |
|---|
cmake:enableFullFeatureSet | Extension is fully activated |
useCMakePresets | Presets mode is active |
!useCMakePresets | Kits/variants mode is active |
view == cmake.projectStatus && viewItem == 'kit' | Specific tree-view item |
viewItem =~ /configPreset/ | Regex match on tree-view item |
Step 2 — Add the English string to package.nls.json
"cmake-tools.command.cmake.myCommand.title": "My Command Title"
For titles containing the product name, use the object form with a translator comment:
"cmake-tools.command.cmake.myCommand.title": {
"message": "Do Something with CMake Tools",
"comment": ["The text 'CMake Tools' should not be localized."]
}
Do not modify any file under i18n/.
Step 3 — Register the command in src/extension.ts
Add the method name to the funs array (search for const funs: near the end of the file). The register() helper
auto-generates the command ID cmake.<name>, wraps it with debug logging, and hands
the promise to rollbar.takePromise() for error tracking.
const funs: (keyof ExtensionManager)[] = [
'myCommand',
];
That's it — no manual registerCommand call needed. The loop that follows handles registration automatically:
for (const key of funs) {
context.subscriptions.push(register(key));
}
Only use manual vscode.commands.registerCommand() for commands that need
custom argument handling (e.g., tree-view context-menu commands that receive
a node argument). Most commands go through the funs array.
Step 4 — Implement the handler on ExtensionManager
Add a method to the ExtensionManager class in src/extension.ts. The method
name must match the string added to the funs array.
Pattern A — Delegate to CMakeProject (most common)
myCommand(folder?: vscode.WorkspaceFolder) {
telemetry.logEvent('myCommand');
return this.runCMakeCommand(
cmakeProject => cmakeProject.myCommand(),
folder,
undefined,
true
);
}
Then implement the actual logic on CMakeProject in src/cmakeProject.ts.
Pattern B — Run for all projects
myCommandAll() {
telemetry.logEvent('myCommand', { all: 'true' });
return this.runCMakeCommandForAll(
cmakeProject => cmakeProject.myCommand()
);
}
Pattern C — Direct implementation (no CMakeProject delegation)
async myCommand() {
telemetry.logEvent('myCommand');
const result = await vscode.window.showQuickPick(items);
if (!result) {
return;
}
}
Key helpers
| Helper | Use when |
|---|
this.runCMakeCommand(cmd, folder) | Single-project command |
this.runCMakeCommandForAll(cmd) | Runs on every open CMake project |
this.runCMakeCommandForProject(cmd, project) | Specific project instance |
Step 5 — Add a CHANGELOG entry
Add an entry under the current version in CHANGELOG.md, in the Features: section.
Verification checklist
See also: .github/copilot-instructions.md for project-wide conventions.