Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@
"markdownDescription": "并行编译使用的 CPU 核心数(默认为 1)。\n\n设置大于 1 的值可以加快编译速度,例如:\n- `1`: 单核编译\n- `4`: 使用 4 个核心并行编译\n- `8`: 使用 8 个核心并行编译",
"scope": "resource",
"order": 1
},
"smart.useTerminalMenuconfig": {
"type": "boolean",
"default": false,
"description": "是否只使用 scons --menuconfig 方式进行配置(默认为 false)。启用后将不使用图形化 Kconfig 编辑器插件。",
"markdownDescription": "是否只使用 `scons --menuconfig` 方式进行配置(默认为 false)。\n\n- `false`: 优先使用已安装的 Kconfig 图形化编辑器插件\n- `true`: 始终使用终端字符界面方式",
"scope": "resource",
"order": 2
}
}
},
Expand Down
22 changes: 15 additions & 7 deletions src/dock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fs from 'fs';
import { getWorkspaceFolder, isRTThreadProject, isRTThreadWorksapce } from './api';
import { buildGroupsTree, buildProjectTree, buildEmptyProjectTree, ProjectTreeItem, listFolderTreeItem, buildBSPTree, setTreeDataChangeEmitter } from './project/tree';
import { cmds } from './cmds/index';
import { getMenuconfigMethod } from './smart';

class CmdTreeDataProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
getTreeItem(element: vscode.TreeItem): vscode.TreeItem {
Expand Down Expand Up @@ -107,18 +108,25 @@ class CmdTreeDataProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
} else {
let children:any = [];

const kconfig = vscode.extensions.getExtension('rt-thread.rt-thread-kconfig');

for (const [key, value] of Object.entries(cmds)) {
if (element.label === value.label) {
for (const cmdItem of value.subcmds) {
let item = new vscode.TreeItem(cmdItem.name);
item.iconPath = new vscode.ThemeIcon(cmdItem.iconId);
if (cmdItem.name === 'menuconfig' && kconfig !== undefined) {
item.command = {
command: "rt-thread-kconfig.menuconfig.windows",
title: cmdItem.cmd.title
};
if (cmdItem.name === 'menuconfig') {
const menuconfigMethod = getMenuconfigMethod();
if (menuconfigMethod.type === 'extension') {
item.command = {
command: menuconfigMethod.command!,
title: cmdItem.cmd.title
};
} else {
item.command = {
command: "extension.executeCommand",
title: cmdItem.cmd.title,
arguments: [menuconfigMethod.terminal!],
Comment thread
BernardXiong marked this conversation as resolved.
};
}
}
else {
item.command = {
Expand Down
52 changes: 49 additions & 3 deletions src/project/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as path from 'path';
import { getWorkspaceFolder } from '../api';
import { executeCommand } from '../terminal';
import { readWorkspaceJson, writeWorkspaceJson } from '../webviews/project';
import { getMenuconfigMethod, MENUCONFIG_COMMANDS } from '../smart';

let _currentProject: string = '';

Expand All @@ -26,11 +27,56 @@ export function fastBuildProject(arg: any) {
return;
}

/**
* Helper function to execute terminal-based menuconfig for a BSP project
* @param bspPath The path to the BSP project
*/
function executeTerminalMenuconfig(bspPath: string) {
const cmd = 'scons -C ' + bspPath + ' --menuconfig';
executeCommand(cmd);
}

export function configProject(arg: any) {
if (arg) {
let cmd = 'scons -C ' + arg.fn + ' --menuconfig';

executeCommand(cmd);
const menuconfigMethod = getMenuconfigMethod();

if (menuconfigMethod.type === 'extension') {
// For rt-thread-kconfig extension, it handles multi-BSP scenarios automatically
if (menuconfigMethod.command === MENUCONFIG_COMMANDS.RT_THREAD_KCONFIG) {
// Change to the BSP directory first
executeCommand('cd ' + arg.fn);
// Execute the extension command
vscode.commands.executeCommand(menuconfigMethod.command);
}
// For vscode-kconfig-visual-editor, we need to open the Kconfig file explicitly
else if (menuconfigMethod.command === MENUCONFIG_COMMANDS.KCONFIG_VISUAL_EDITOR) {
const kconfigPath = path.join(arg.fn, 'Kconfig');
if (fs.existsSync(kconfigPath)) {
// Open the Kconfig file with the visual editor
vscode.workspace.openTextDocument(kconfigPath).then(
doc => {
vscode.window.showTextDocument(doc);
},
error => {
vscode.window.showErrorMessage(`Failed to open Kconfig file: ${error.message}`);
// Fallback to terminal on error
executeTerminalMenuconfig(arg.fn);
}
);
} else {
// Fallback to terminal if Kconfig doesn't exist
executeTerminalMenuconfig(arg.fn);
}
}
else {
// Generic extension command
executeCommand('cd ' + arg.fn);
vscode.commands.executeCommand(menuconfigMethod.command!);
}
Copy link

Copilot AI Oct 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'else' block at lines 64-68 is unreachable because the two preceding if conditions (lines 36 and 43) already cover all possible values of menuconfigMethod.command from MENUCONFIG_COMMANDS. This dead code should be removed or the logic should be restructured if additional extension commands are expected in the future.

Suggested change
else {
// Generic extension command
executeCommand('cd ' + arg.fn);
vscode.commands.executeCommand(menuconfigMethod.command!);
}

Copilot uses AI. Check for mistakes.
} else {
// For terminal-based menuconfig
executeTerminalMenuconfig(arg.fn);
}
}

return;
Expand Down
70 changes: 70 additions & 0 deletions src/smart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,73 @@ export function getParallelBuildNumber() {

return parallel;
}

/* get whether to use terminal menuconfig only */
export function getUseTerminalMenuconfig() {
const config = vscode.workspace.getConfiguration('smart');
const useTerminal = config.get('useTerminalMenuconfig') as boolean;

return useTerminal;
}

/**
* Menuconfig method type
*/
export interface MenuconfigMethod {
type: 'extension' | 'terminal';
command?: string; // VS Code command for extension type
terminal?: string; // Terminal command for terminal type
}

/**
* Extension command constants for menuconfig
*/
export const MENUCONFIG_COMMANDS = {
RT_THREAD_KCONFIG: 'rt-thread-kconfig.menuconfig.windows',
KCONFIG_VISUAL_EDITOR: 'kconfig-visual-editor.open'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flyingcys 这里的扩展id对吗?谢谢

};

/**
* Get the appropriate menuconfig method based on installed extensions and configuration
* Priority:
* 1. If useTerminalMenuconfig is true, always use terminal
* 2. Check for rt-thread.rt-thread-kconfig extension
* 3. Check for ai-embedded.vscode-kconfig-visual-editor extension
* 4. Fall back to terminal scons --menuconfig
*
* @param kconfigPath Optional Kconfig file path for vscode-kconfig-visual-editor
* @returns MenuconfigMethod object describing the method to use
*/
export function getMenuconfigMethod(kconfigPath?: string): MenuconfigMethod {
// Check if user wants to force terminal menuconfig
if (getUseTerminalMenuconfig()) {
return {
type: 'terminal',
terminal: 'scons --menuconfig'
};
}

// Priority 1: Check for rt-thread-kconfig extension
const rtThreadKconfig = vscode.extensions.getExtension('rt-thread.rt-thread-kconfig');
if (rtThreadKconfig !== undefined) {
return {
type: 'extension',
command: MENUCONFIG_COMMANDS.RT_THREAD_KCONFIG
};
}

// Priority 2: Check for vscode-kconfig-visual-editor extension
const kconfigVisualEditor = vscode.extensions.getExtension('ai-embedded.vscode-kconfig-visual-editor');
if (kconfigVisualEditor !== undefined) {
return {
type: 'extension',
command: MENUCONFIG_COMMANDS.KCONFIG_VISUAL_EDITOR,
};
}

// Priority 3: Fall back to terminal menuconfig
return {
type: 'terminal',
terminal: 'scons --menuconfig'
};
}