Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
"command": "extension.openTerminalProject",
"title": "Open RT-Thread Terminal",
"icon": "$(console)"
},
{
"command": "extension.handleTreeItemClick",
"title": "Handle Tree Item Click"
}
],
"menus": {
Expand All @@ -119,11 +123,6 @@
}
],
"view/item/context": [
{
"command": "extension.switchProject",
"when": "view == projectFilesId && viewItem == project_bsp",
"group": "inline"
},
{
"command": "extension.fastBuildProject",
"when": "view == projectFilesId && viewItem == project_bsp",
Expand Down
8 changes: 7 additions & 1 deletion src/dock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as vscode from 'vscode';
import os from 'os';
import fs from 'fs';
import { getWorkspaceFolder, isRTThreadProject, isRTThreadWorksapce } from './api';
import { buildGroupsTree, buildProjectTree, buildEmptyProjectTree, ProjectTreeItem, listFolderTreeItem, buildBSPTree } from './project/tree';
import { buildGroupsTree, buildProjectTree, buildEmptyProjectTree, ProjectTreeItem, listFolderTreeItem, buildBSPTree, setTreeDataChangeEmitter } from './project/tree';
import { cmds } from './cmds/index';

class CmdTreeDataProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
Expand Down Expand Up @@ -188,6 +188,10 @@ class ProjectFilesDataProvider implements vscode.TreeDataProvider<ProjectTreeIte
private _onDidChangeTreeData: vscode.EventEmitter<ProjectTreeItem | undefined> = new vscode.EventEmitter<ProjectTreeItem | undefined>();
readonly onDidChangeTreeData: vscode.Event<ProjectTreeItem | undefined> = this._onDidChangeTreeData.event;

getTreeDataChangeEmitter(): vscode.EventEmitter<ProjectTreeItem | undefined> {
return this._onDidChangeTreeData;
}

getTreeItem(element: ProjectTreeItem): vscode.TreeItem {
return element;
}
Expand Down Expand Up @@ -291,6 +295,8 @@ export function initDockView(context: vscode.ExtensionContext) {
treeDataProvider: _projectFilesDataProvider, showCollapseAll: true
});

setTreeDataChangeEmitter(_projectFilesDataProvider.getTreeDataChangeEmitter());

context.subscriptions.push(view);
vscode.commands.registerCommand('extension.refreshRTThread', () => refreshProjectFilesAndGroups());

Expand Down
10 changes: 10 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { setupVEnv } from './venv';
import { initAPI } from './api';
import { openWorkspaceProjectsWebview } from './webviews/project';
import { initProjectTree } from './project/tree';
import { DecorationProvider } from './project/fileDecorationProvider';
import { getCurrentProjectInWorkspace } from './webviews/project';

let _context: vscode.ExtensionContext;

Expand Down Expand Up @@ -47,6 +49,14 @@ export async function activate(context: vscode.ExtensionContext) {
isRTThreadWorksapce = true;
vscode.commands.executeCommand('setContext', 'isRTThreadWorksapce', true);
context.workspaceState.update('isRTThreadWorksapce', isRTThreadWorksapce);

new DecorationProvider(context);

// get current project from workspace.json file
let currentProject = getCurrentProjectInWorkspace();
if (currentProject) {
DecorationProvider.getInstance().markFile(vscode.Uri.file(currentProject));
}
}
}
else {
Expand Down
12 changes: 12 additions & 0 deletions src/project/cmd.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as os from 'os';
import * as fs from 'fs';
import * as vscode from 'vscode';

import { getWorkspaceFolder } from '../api';
import { executeCommand } from '../terminal';
import { readWorkspaceJson, writeWorkspaceJson } from '../webviews/project';

let _currentProject: string = '';

Expand Down Expand Up @@ -40,6 +42,16 @@ export function openTerminalProject(arg: any) {
export function setCurrentProject(arg: any) {
if (arg) {
_currentProject = arg.fn;

let cmd = 'scons -C ' + arg.fn + ' --target=vsc_workspace';
executeCommand(cmd);

// update workspace.json file
let workspaceJson = readWorkspaceJson();
if (workspaceJson) {
workspaceJson.currentProject = arg.fn;
writeWorkspaceJson(workspaceJson);
}
}

return;
Expand Down
65 changes: 65 additions & 0 deletions src/project/fileDecorationProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
CancellationToken,
Event,
EventEmitter,
ExtensionContext,
FileDecoration,
FileDecorationProvider,
ThemeColor,
Uri,
window,
} from "vscode";

export class DecorationProvider implements FileDecorationProvider {
private readonly _onDidChangeFileDecorations: EventEmitter<Uri | Uri[]> =
new EventEmitter<Uri | Uri[]>();
readonly onDidChangeFileDecorations: Event<Uri | Uri[]> =
this._onDidChangeFileDecorations.event;
public markedFiles: Set<string> = new Set<string>();
private static instance: DecorationProvider;

constructor(context: ExtensionContext) {
// 注册文件装饰提供者
context.subscriptions.push(
window.registerFileDecorationProvider(this),
);

DecorationProvider.instance = this;
}

static getInstance(): DecorationProvider {
return DecorationProvider.instance;
}

provideFileDecoration(uri: Uri, token: CancellationToken): FileDecoration | undefined {
if (token.isCancellationRequested) {
return;
}

if (this.markedFiles.has(uri.fsPath)) {
return {
propagate: true,
badge: "📌",
color: new ThemeColor("terminal.ansiCyan"),
};
}
}

public async markFile(uri: Uri) {
if (!this.markedFiles.has(uri.fsPath)) {
this.markedFiles.add(uri.fsPath);
this._onDidChangeFileDecorations.fire(uri);
}
}

public async unmarkFile(uri: Uri) {
if (this.markedFiles.has(uri.fsPath)) {
this.markedFiles.delete(uri.fsPath);
this._onDidChangeFileDecorations.fire(uri);
}
}

public async unmarkAllFiles() {
this.markedFiles.clear();
}
}
57 changes: 54 additions & 3 deletions src/project/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'path';
import * as vscode from 'vscode';
import fs from 'fs';
import { getWorkspaceFolder, getExtensionPath } from '../api';
import { DecorationProvider } from './fileDecorationProvider';

/*
* contexType -> contextValue as following value:
Expand All @@ -11,6 +12,12 @@ import { getWorkspaceFolder, getExtensionPath } from '../api';
* project_bsp
*/

// 全局变量记录当前选中的project_bsp项目
let currentSelectedBspItem: ProjectTreeItem | null = null;

// 添加树视图刷新事件发射器
let _onDidChangeTreeData: vscode.EventEmitter<ProjectTreeItem | undefined> | null = null;

export class ProjectTreeItem extends vscode.TreeItem {
children: ProjectTreeItem[];
fn: string = '';
Expand Down Expand Up @@ -58,12 +65,16 @@ export class ProjectTreeItem extends vscode.TreeItem {
else if (contextType == 'project_bsp') {
this.command = {
title: this.name,
command: 'extension.switchProject',
command: 'extension.handleTreeItemClick',
tooltip: this.name,
arguments: [
this
]
};

// with resourceUri, the item will be rendered as a file icon
// then the item can be marked with a decoration
this.resourceUri = vscode.Uri.file(this.fn);
}
}
}
Expand Down Expand Up @@ -333,7 +344,47 @@ export function initProjectTree(context:vscode.ExtensionContext) {
vscode.commands.registerCommand('extension.openTerminalProject', (arg) => {
openTerminalProject(arg);
});
vscode.commands.registerCommand('extension.switchProject', (arg) => {
setCurrentProject(arg);

// Add double-clicked
let lastClickTime = 0;
let lastClickedItem: ProjectTreeItem | null = null;

vscode.commands.registerCommand('extension.handleTreeItemClick', (item: ProjectTreeItem) => {
const currentTime = Date.now();
const doubleClickThreshold = 500; // 500ms内的两次点击被认为是双击

if (item.contextType === 'project_bsp') {
if (lastClickedItem === item && (currentTime - lastClickTime) < doubleClickThreshold) {
if (currentSelectedBspItem && currentSelectedBspItem.fn === item.fn) {
return;
}

// double clicked
if (currentSelectedBspItem && currentSelectedBspItem.fn != item.fn) {
DecorationProvider.getInstance().unmarkFile(vscode.Uri.file(currentSelectedBspItem.fn));
}

currentSelectedBspItem = item;
DecorationProvider.getInstance().markFile(vscode.Uri.file(item.fn));
setCurrentProject(item);

if (_onDidChangeTreeData) {
_onDidChangeTreeData.fire(undefined);
}

// reset status
lastClickTime = 0;
lastClickedItem = null;
} else {
// one-clicked, just record it.
lastClickTime = currentTime;
lastClickedItem = item;
}
}
});
}

// 导出函数用于设置树视图刷新事件发射器
export function setTreeDataChangeEmitter(emitter: vscode.EventEmitter<ProjectTreeItem | undefined>) {
_onDidChangeTreeData = emitter;
}
35 changes: 22 additions & 13 deletions src/vue/projects/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
可以在感兴趣的BSP/工程项上✔,然后保存配置,将会在侧边栏中显示对应列表。<br>
<hr>

<el-button @click="reloadBSPProjects" hidden>加载列表</el-button>
<el-button @click="collapseAll">折叠全部列表</el-button>

<el-button type="primary" @click="saveBSPProjects">保存列表配置</el-button>
<div style="text-align: right; margin-bottom: 10px;">
<el-button @click="reloadBSPProjects" style="display: none;">加载列表</el-button>
<el-button @click="collapseAll">折叠全部列表</el-button>
<el-button type="primary" @click="saveBSPProjects">保存列表配置</el-button>
</div>

<el-table ref="tableRef" v-loading="loading" :data="tableData" style="width: 100%" row-key="id"
:expand-row-keys="expandedRowKeys">
Expand All @@ -20,7 +21,7 @@
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { onMounted, ref, nextTick } from 'vue';
import { imgUrl } from '../assets/img';
import { sendCommand } from '../api/vscode';

Expand All @@ -42,9 +43,11 @@ const reloadBSPProjects = () => {

const saveBSPProjects = () => {
let args:string[] = [];
const selectedRows = tableRef.value.getSelectionRows();
if (selectedRows.length > 0) {
args = selectedRows.map(row => row.path);
if (tableRef.value) {
const selectedRows = (tableRef.value as any).getSelectionRows();
if (selectedRows.length > 0) {
args = selectedRows.map(row => row.path);
}
}

sendCommand('saveBSPProjects', [args]);
Expand All @@ -59,14 +62,20 @@ onMounted(() => {

switch (message.command) {
case 'updateProjects':
// console.log(message);
tableData.value = message.data.dirs;
let stars:string[] = message.data.stars;
tableData.value.forEach((item, index) => {
if (stars.includes(item.path)) {
tableRef.value?.toggleRowSelection({ id: item.id }, true)
}

// 使用 nextTick 确保 DOM 更新完成后再执行选择操作
nextTick(() => {
tableData.value.forEach((item, index) => {
if (stars.includes(item.path)) {
if (tableRef.value) {
(tableRef.value as any).toggleRowSelection(item, true);
}
}
});
});

loading.value = false; // 停止加载动画
break;

Expand Down
Loading