Skip to content

Commit 7f44341

Browse files
authored
Merge pull request #8 from RT-Thread/project
Add workspace/project features.
2 parents 520d1a9 + 0c2ff84 commit 7f44341

File tree

13 files changed

+618
-53
lines changed

13 files changed

+618
-53
lines changed

package.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,40 @@
7373
"command": "extension.refreshRTThread",
7474
"title": "Refresh",
7575
"icon": "$(sync)"
76+
},
77+
{
78+
"command": "extension.showWorkspaceSettings",
79+
"title": "Show Workspace Settings",
80+
"icon": "$(settings-gear)"
81+
},
82+
{
83+
"command": "extension.switchProject",
84+
"title": "Switch project to this bsp",
85+
"icon": "$(pass-filled)"
86+
},
87+
{
88+
"command": "extension.fastBuildProject",
89+
"title": "Build (-j CPU)...",
90+
"icon": "$(github-action)"
91+
},
92+
{
93+
"command": "extension.configProject",
94+
"title": "Menuconfig",
95+
"icon": "$(gear)"
96+
},
97+
{
98+
"command": "extension.openTerminalProject",
99+
"title": "Open RT-Thread Terminal",
100+
"icon": "$(console)"
76101
}
77102
],
78103
"menus": {
79104
"view/title": [
105+
{
106+
"command": "extension.showWorkspaceSettings",
107+
"when": "(view == projectFilesId || view == groupsId) && isRTThreadWorksapce",
108+
"group": "navigation"
109+
},
80110
{
81111
"command": "extension.refreshRTThread",
82112
"when": "view == projectFilesId || view == groupsId",
@@ -87,6 +117,28 @@
87117
"when": "(view == projectFilesId || view == groupsId) && isRTThread",
88118
"group": "navigation"
89119
}
120+
],
121+
"view/item/context": [
122+
{
123+
"command": "extension.switchProject",
124+
"when": "view == projectFilesId && viewItem == project_bsp",
125+
"group": "inline"
126+
},
127+
{
128+
"command": "extension.fastBuildProject",
129+
"when": "view == projectFilesId && viewItem == project_bsp",
130+
"group": "inline"
131+
},
132+
{
133+
"command": "extension.configProject",
134+
"when": "view == projectFilesId && viewItem == project_bsp",
135+
"group": "inline"
136+
},
137+
{
138+
"command": "extension.openTerminalProject",
139+
"when": "view == projectFilesId && viewItem == project_bsp",
140+
"group": "inline"
141+
}
90142
]
91143
},
92144
"configuration": {

src/api.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ import * as path from 'path';
66
import { executeCommand } from './terminal';
77

88
let _context: vscode.ExtensionContext;
9-
let _isRTThread = false;
109
let _bi: any[] = [];
1110

1211
export function isRTThreadProject() {
13-
return _isRTThread;
12+
let status = _context.workspaceState.get<boolean>('isRTThread') || false;
13+
return status;
1414
}
1515

16-
export function initAPI(context:vscode.ExtensionContext, isRTThreadEnv: boolean) {
16+
export function isRTThreadWorksapce() {
17+
let status = _context.workspaceState.get<boolean>('isRTThreadWorksapce') || false;
18+
return status;
19+
}
20+
21+
export function initAPI(context:vscode.ExtensionContext) {
1722
_context = context;
18-
_isRTThread = isRTThreadEnv;
1923

2024
// read resources/bi.json for boards information
2125
_bi = readJsonObject(path.join(getExtensionPath(), "resources", "bi.json"));
@@ -149,7 +153,7 @@ export async function openFolder(uri?: string) {
149153
canSelectFolders: true,
150154
canSelectFiles: false,
151155
canSelectMany: false,
152-
});
156+
});
153157
}
154158
else {
155159
selectedFolder = await vscode.window.showOpenDialog({

src/cmds/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ export let cmds: Object = {
5050
]
5151
}
5252
},
53+
{
54+
name : "fix config",
55+
iconId : "layers-active",
56+
cmd : {
57+
title : "fix-config",
58+
arguments : [
59+
"scons --pyconfig-silent"
60+
]
61+
}
62+
},
5363
{
5464
name : "vscode settings",
5565
iconId : "compare-changes",

src/dock.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import path from 'path';
22
import * as vscode from 'vscode';
33
import os from 'os';
44
import fs from 'fs';
5-
import { getWorkspaceFolder, isRTThreadProject } from './api';
6-
import { buildGroupsTree, buildProjectTree, buildEmptyProjectTree, ProjectTreeItem, listFolderTreeItem } from './project/tree';
5+
import { getWorkspaceFolder, isRTThreadProject, isRTThreadWorksapce } from './api';
6+
import { buildGroupsTree, buildProjectTree, buildEmptyProjectTree, ProjectTreeItem, listFolderTreeItem, buildBSPTree } from './project/tree';
77
import { cmds } from './cmds/index';
88

99
class CmdTreeDataProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
@@ -12,7 +12,13 @@ class CmdTreeDataProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
1212
}
1313

1414
getChildren(element?: vscode.TreeItem): vscode.ProviderResult<vscode.TreeItem[]> {
15-
if (isRTThreadProject() != true) {
15+
const isRTT = isRTThreadProject();
16+
const isRTTWorksapce = isRTThreadWorksapce();
17+
if (isRTT != true && isRTTWorksapce != true) {
18+
console.log("not RT-Thread project or workspace, return empty tree item.");
19+
}
20+
21+
if (isRTThreadProject() != true && isRTThreadWorksapce() != true) {
1622
// only show Home command
1723
let home = new vscode.TreeItem("Home", vscode.TreeItemCollapsibleState.None);
1824
home.iconPath = new vscode.ThemeIcon("home");
@@ -114,6 +120,22 @@ class GroupsDataProvider implements vscode.TreeDataProvider<ProjectTreeItem> {
114120
return buildEmptyProjectTree();
115121
}
116122
}
123+
else {
124+
jsonPath = getWorkspaceFolder() + "/.vscode/workspace.json";
125+
if (fs.existsSync(jsonPath)) {
126+
try {
127+
const json = fs.readFileSync(jsonPath, 'utf8');
128+
const jsonNode = JSON.parse(json);
129+
130+
if (jsonNode.hasOwnProperty("bsps")) {
131+
return buildBSPTree(jsonNode);
132+
}
133+
}
134+
catch (err) {
135+
return buildEmptyProjectTree();
136+
}
137+
}
138+
}
117139

118140
/* build empty project tree */
119141
return buildEmptyProjectTree();
@@ -212,6 +234,21 @@ class ProjectFilesDataProvider implements vscode.TreeDataProvider<ProjectTreeIte
212234
}
213235
}
214236

237+
let workspacePath = getWorkspaceFolder() + "/.vscode/workspace.json";
238+
if (fs.existsSync(workspacePath)) {
239+
try {
240+
const json = fs.readFileSync(workspacePath, 'utf8');
241+
const jsonNode = JSON.parse(json);
242+
243+
if (jsonNode.hasOwnProperty("bsps")) {
244+
return buildBSPTree(jsonNode);
245+
}
246+
}
247+
catch (err) {
248+
return buildEmptyProjectTree();
249+
}
250+
}
251+
215252
/* build empty project tree */
216253
return buildEmptyProjectTree();
217254
}
@@ -253,6 +290,7 @@ export function initDockView(context: vscode.ExtensionContext) {
253290
const view = vscode.window.createTreeView('projectFilesId', {
254291
treeDataProvider: _projectFilesDataProvider, showCollapseAll: true
255292
});
293+
256294
context.subscriptions.push(view);
257295
vscode.commands.registerCommand('extension.refreshRTThread', () => refreshProjectFilesAndGroups());
258296

src/extension.ts

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,55 @@ import { getMenuItems, getParallelBuildNumber } from './smart';
1212
import { initDockView } from './dock';
1313
import { setupVEnv } from './venv';
1414
import { initAPI } from './api';
15+
import { openWorkspaceProjectsWebview } from './webviews/project';
16+
import { initProjectTree } from './project/tree';
1517

1618
let _context: vscode.ExtensionContext;
1719

20+
// 有两种模式
21+
// isRTThreadWorksapce - workspace模式,会定位.vscode/workspace.json文件是否存在,是否启用
22+
// isRTThread - 项目模式,rtconfig.h文件是否存在
23+
1824
export async function activate(context: vscode.ExtensionContext) {
1925
let isRTThread: boolean = false;
20-
const workspaceFolders = vscode.workspace.workspaceFolders;
26+
let isRTThreadWorksapce: boolean = false;
2127

2228
_context = context;
29+
30+
// init context for isRTThread, isRTThreadWorksapce
31+
vscode.commands.executeCommand('setContext', 'isRTThread', isRTThread);
32+
context.workspaceState.update('isRTThread', isRTThread);
33+
vscode.commands.executeCommand('setContext', 'isRTThreadWorksapce', isRTThreadWorksapce);
34+
context.workspaceState.update('isRTThreadWorksapce', isRTThreadWorksapce);
35+
initAPI(context);
36+
37+
const workspaceFolders = vscode.workspace.workspaceFolders;
2338
if (workspaceFolders) {
2439
const workspacePath = workspaceFolders[0].uri.fsPath;
25-
// check rtconfig.h exists
26-
const rtconfigPath = path.join(workspacePath, 'rtconfig.h');
27-
if (fs.existsSync(rtconfigPath)) {
28-
/* The workspace is a RT-Thread Project*/
29-
isRTThread = true;
30-
initAPI(context, isRTThread);
31-
vscode.commands.executeCommand('setContext', 'isRTThread', true);
3240

41+
const rtthreadWorkspace = path.join(workspacePath, '.vscode', 'workspace.json');
42+
if (fs.existsSync(rtthreadWorkspace)) {
43+
const json = fs.readFileSync(rtthreadWorkspace, 'utf8');
44+
const jsonNode = JSON.parse(json);
45+
46+
if (jsonNode.hasOwnProperty("bsps")) {
47+
isRTThreadWorksapce = true;
48+
vscode.commands.executeCommand('setContext', 'isRTThreadWorksapce', true);
49+
context.workspaceState.update('isRTThreadWorksapce', isRTThreadWorksapce);
50+
}
51+
}
52+
else {
53+
// check rtconfig.h exists
54+
const rtconfigPath = path.join(workspacePath, 'rtconfig.h');
55+
if (fs.existsSync(rtconfigPath)) {
56+
/* The workspace is a RT-Thread Project*/
57+
isRTThread = true;
58+
vscode.commands.executeCommand('setContext', 'isRTThread', true);
59+
context.workspaceState.update('isRTThread', isRTThread);
60+
}
61+
}
62+
63+
if (isRTThread || isRTThreadWorksapce) {
3364
// if it's Windows system
3465
if (os.platform() === 'win32') {
3566
await setupVEnv();
@@ -42,7 +73,7 @@ export async function activate(context: vscode.ExtensionContext) {
4273
// register commands
4374
vscode.commands.registerCommand('extension.showAbout', () => {
4475
openAboutWebview(context);
45-
});
76+
});
4677
vscode.commands.registerCommand('extension.executeCommand', (arg1, arg2) => {
4778
if (arg1)
4879
{
@@ -60,21 +91,35 @@ export async function activate(context: vscode.ExtensionContext) {
6091
}
6192
})
6293
}
63-
else {
64-
isRTThread = false;
65-
vscode.commands.executeCommand('setContext', 'isRTThread', false);
66-
initAPI(context, isRTThread);
67-
}
68-
}
69-
else {
70-
initAPI(context, isRTThread);
7194
}
7295

7396
vscode.commands.registerCommand('extension.showHome', () => {
7497
openHomeWebview(context);
7598
});
99+
if (isRTThreadWorksapce) {
100+
vscode.commands.registerCommand('extension.showWorkspaceSettings', () => {
101+
openWorkspaceProjectsWebview(context);
102+
});
103+
initProjectTree(context);
104+
}
105+
76106
/* initialize dock view always */
77107
initDockView(context);
108+
initExperimentStatusBarItem(context)
109+
}
110+
111+
function initExperimentStatusBarItem(context: vscode.ExtensionContext) {
112+
if (false){
113+
const statusItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 5);
114+
statusItem.text = '$(beaker) 实验性功能';
115+
statusItem.tooltip = 'Experimental features';
116+
statusItem.command = 'extension.Experimental';
117+
statusItem.show();
118+
119+
vscode.commands.registerCommand('extension.Experimental', () => {
120+
console.log('Experimental features are not available yet.');
121+
});
122+
}
78123
}
79124

80125
function setupStatusBarItems(context: vscode.ExtensionContext) {

src/project/cmd.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import * as os from 'os';
2+
import * as fs from 'fs';
3+
4+
import { getWorkspaceFolder } from '../api';
5+
import { executeCommand } from '../terminal';
6+
7+
let _currentProject: string = '';
8+
9+
export function fastBuildProject(arg: any) {
10+
if (arg) {
11+
const cpus = os.cpus().length;
12+
let cmd = 'scons -C ' + arg.fn + ' -j ' + cpus.toString();
13+
14+
executeCommand(cmd);
15+
}
16+
17+
return;
18+
}
19+
20+
export function configProject(arg: any) {
21+
if (arg) {
22+
let cmd = 'scons -C ' + arg.fn + ' --menuconfig';
23+
24+
executeCommand(cmd);
25+
}
26+
27+
return;
28+
}
29+
30+
export function openTerminalProject(arg: any) {
31+
if (arg) {
32+
let cmd = 'cd ' + arg.fn;
33+
34+
executeCommand(cmd);
35+
}
36+
37+
return;
38+
}
39+
40+
export function setCurrentProject(arg: any) {
41+
if (arg) {
42+
_currentProject = arg.fn;
43+
}
44+
45+
return;
46+
}
47+
48+
export function getCurrentProject() {
49+
let rtconfig = getWorkspaceFolder() + '/' + 'rtconfig.h';
50+
51+
if (fs.existsSync(rtconfig)) {
52+
return getWorkspaceFolder();
53+
}
54+
55+
return _currentProject;
56+
}

0 commit comments

Comments
 (0)