From b6708d327854494148f27c0fdcb612a41324e60d Mon Sep 17 00:00:00 2001 From: LSTM-Kirigaya <1193466151@qq.com> Date: Sat, 14 Sep 2024 00:31:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=B8=AD=E5=8E=BB=E9=99=A4?= =?UTF-8?q?=E4=BA=86=200.3.3=20=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- src/extension.ts | 16 +--- src/function/hdlDoc/markdown.ts | 4 +- src/function/index.ts | 29 +++--- src/function/lsp/hover/vlog.ts | 8 +- src/function/lsp/util/feature.ts | 148 ++++++++++++++++++++++++++++++- src/function/sim/simulate.ts | 40 ++++----- src/function/treeView/command.ts | 18 +++- src/function/treeView/tree.ts | 9 +- src/global/prjInfo.ts | 6 +- src/hdlParser/core.ts | 8 +- src/manager/libPick.ts | 47 +++++++--- 12 files changed, 254 insertions(+), 84 deletions(-) diff --git a/package.json b/package.json index 2eb854f..4928430 100644 --- a/package.json +++ b/package.json @@ -593,7 +593,10 @@ { "command": "digital-ide.tool.icarus.simulateFile", "group": "inline@1", - "when": "view == digital-ide-treeView-arch && viewItem == file" + "when": "view == digital-ide-treeView-arch && viewItem == file", + "args": { + "file": "${viewItem}" + } }, { "command": "digital-ide.netlist.show", diff --git a/src/extension.ts b/src/extension.ts index e1cce37..ff6cb06 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -18,13 +18,8 @@ async function registerCommand(context: vscode.ExtensionContext) { func.registerFSM(context); func.registerNetlist(context); func.registerWaveViewer(context); -<<<<<<< HEAD - lspClient.activate(context); - lspClient.activateVHDL(context); -======= - - lspClient.activate(context); ->>>>>>> 199b7a8af3ea01baea4b20c89273a490dc0dc9d2 + // lspClient.activate(context); + // lspClient.activateVHDL(context); } @@ -66,9 +61,6 @@ export function activate(context: vscode.ExtensionContext) { } export function deactivate() { - lspClient.deactivate(); -<<<<<<< HEAD - lspClient.deactivateVHDL(); -======= ->>>>>>> 199b7a8af3ea01baea4b20c89273a490dc0dc9d2 + // lspClient.deactivate(); + // lspClient.deactivateVHDL(); } \ No newline at end of file diff --git a/src/function/hdlDoc/markdown.ts b/src/function/hdlDoc/markdown.ts index d9877aa..0c97c95 100644 --- a/src/function/hdlDoc/markdown.ts +++ b/src/function/hdlDoc/markdown.ts @@ -79,9 +79,11 @@ function makeTableFromObjArray(md: MarkdownString, array: any[], name: string, f async function patchComment(path: AbsPath, ports: (HdlModulePort | HdlModuleParam)[]) { if (!ports || !ports.length) { return; - } + } const ranges = ports.map(port => port.range); const comments = await getSymbolComments(path, ranges); + console.log(ranges); + for (let i = 0; i < ports.length; ++ i) { let inlineComment = comments[i].replace(/\n/, ' '); if (inlineComment.startsWith('//') || inlineComment.startsWith('--')) { diff --git a/src/function/index.ts b/src/function/index.ts index 3b103ad..beddf92 100644 --- a/src/function/index.ts +++ b/src/function/index.ts @@ -20,6 +20,7 @@ import * as lspCore from './lsp/core'; import * as FSM from './fsm'; import * as Netlist from './netlist'; import * as WaveView from './dide-viewer'; +import { ModuleDataItem } from './treeView/tree'; function registerDocumentation(context: vscode.ExtensionContext) { vscode.commands.registerCommand('digital-ide.hdlDoc.showWebview', hdlDoc.showDocWebview); @@ -30,7 +31,9 @@ function registerDocumentation(context: vscode.ExtensionContext) { function registerSimulation(context: vscode.ExtensionContext) { vscode.commands.registerCommand('digital-ide.tool.instance', sim.instantiation); vscode.commands.registerCommand('digital-ide.tool.testbench', sim.testbench); - vscode.commands.registerCommand('digital-ide.tool.icarus.simulateFile', sim.Icarus.simulateFile); + vscode.commands.registerCommand('digital-ide.tool.icarus.simulateFile', (view: ModuleDataItem) => { + sim.Icarus.simulateFile(view); + }); } function registerFunctionCommands(context: vscode.ExtensionContext) { @@ -71,21 +74,21 @@ function registerLsp(context: vscode.ExtensionContext) { vscode.commands.registerCommand('digital-ide.vhdl2vlog', uri => lspTranslator.vhdl2vlog(uri)); // verilog lsp - // vscode.languages.registerDocumentSymbolProvider(vlogSelector, lspDocSymbol.vlogDocSymbolProvider); - // vscode.languages.registerDefinitionProvider(vlogSelector, lspDefinition.vlogDefinitionProvider); - // vscode.languages.registerHoverProvider(vlogSelector, lspHover.vlogHoverProvider); - // vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogIncludeCompletionProvider, '/', '"'); - // vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogMacroCompletionProvider, '`'); - // vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogPositionPortProvider, '.'); - // vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogCompletionProvider); - // vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend); + vscode.languages.registerDocumentSymbolProvider(vlogSelector, lspDocSymbol.vlogDocSymbolProvider); + vscode.languages.registerDefinitionProvider(vlogSelector, lspDefinition.vlogDefinitionProvider); + vscode.languages.registerHoverProvider(vlogSelector, lspHover.vlogHoverProvider); + vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogIncludeCompletionProvider, '/', '"'); + vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogMacroCompletionProvider, '`'); + vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogPositionPortProvider, '.'); + vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogCompletionProvider); + vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend); // vhdl lsp - // vscode.languages.registerDocumentSymbolProvider(vhdlSelector, lspDocSymbol.vhdlDocSymbolProvider); - // vscode.languages.registerDefinitionProvider(vhdlSelector, lspDefinition.vhdlDefinitionProvider); - // vscode.languages.registerHoverProvider(vhdlSelector, lspHover.vhdlHoverProvider); - // vscode.languages.registerCompletionItemProvider(vhdlSelector, lspCompletion.vhdlCompletionProvider); + vscode.languages.registerDocumentSymbolProvider(vhdlSelector, lspDocSymbol.vhdlDocSymbolProvider); + vscode.languages.registerDefinitionProvider(vhdlSelector, lspDefinition.vhdlDefinitionProvider); + vscode.languages.registerHoverProvider(vhdlSelector, lspHover.vhdlHoverProvider); + vscode.languages.registerCompletionItemProvider(vhdlSelector, lspCompletion.vhdlCompletionProvider); // tcl lsp diff --git a/src/function/lsp/hover/vlog.ts b/src/function/lsp/hover/vlog.ts index 5e840a6..2521175 100644 --- a/src/function/lsp/hover/vlog.ts +++ b/src/function/lsp/hover/vlog.ts @@ -110,12 +110,12 @@ class VlogHoverProvider implements vscode.HoverProvider { * */ if (util.isPositionInput(lineText, position.character)) { - console.log('enter position input'); + // console.log('enter position input'); const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule); if (!currentInstResult || !currentInstResult.instModPath) { return null; } - console.log(currentInstResult); + // console.log(currentInstResult); const instParamPromise = util.getInstParamByPosition(currentInstResult, position, targetWord); const instPortPromise = util.getInstPortByPosition(currentInstResult, position, targetWord); @@ -155,7 +155,7 @@ class VlogHoverProvider implements vscode.HoverProvider { const paramDesc = util.makeParamDesc(paramResult); content.appendCodeblock(paramDesc, HdlLangID.Verilog); if (paramComment) { - content.appendCodeblock(paramComment, HdlLangID.Verilog); + content.appendMarkdown(paramComment); } return new vscode.Hover(content); } @@ -170,7 +170,7 @@ class VlogHoverProvider implements vscode.HoverProvider { content.appendCodeblock(portDesc, HdlLangID.Verilog); if (portComment) { - content.appendCodeblock(portComment, HdlLangID.Verilog); + content.appendMarkdown(portComment); } return new vscode.Hover(content); } diff --git a/src/function/lsp/util/feature.ts b/src/function/lsp/util/feature.ts index 8c70c53..2f06027 100644 --- a/src/function/lsp/util/feature.ts +++ b/src/function/lsp/util/feature.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import * as vscode from 'vscode'; -import { AbsPath } from '../../../global'; +import { AbsPath, LspOutput } from '../../../global'; import { HdlLangID } from '../../../global/enum'; import { hdlPath, hdlFile } from '../../../hdlFs'; import { Range } from '../../../hdlParser/common'; @@ -126,19 +126,161 @@ function bin2float(bin: string, exp: number, fra: number): number | undefined { } } +function getFullSymbolInfoVlog(document: vscode.TextDocument, range: Range) { + const comments = []; + const currentLine = range.start.line; + const currentText = document.lineAt(currentLine).text; + + // 往上找到第一个非空行 + let nearestFloatLine = currentLine - 1; + while (nearestFloatLine >= 0) { + const linetext = document.lineAt(nearestFloatLine).text.trim(); + if (linetext.length > 0) { + break; + } + nearestFloatLine --; + } + + if (nearestFloatLine >= 0) { + const floatLineText = document.lineAt(nearestFloatLine).text.trim(); + + // 情况 1.1:上面的单行注释 + if (floatLineText.includes('//')) { + const singleLineCommentStartIndex = floatLineText.indexOf('//'); + if (singleLineCommentStartIndex === 0) { + const comment = floatLineText.substring(singleLineCommentStartIndex + 2); + if (comment !== undefined && comment.length > 0) { + comments.push(comment); + } + } + } + + // 情况 1.2:上面的多行注释 + if (floatLineText.includes('*/')) { + const commentEndIndex = floatLineText.indexOf('*/'); + if (!floatLineText.includes('/*') || floatLineText.indexOf('/*') === 0) { + let comment = ''; + for (let lineno = nearestFloatLine; lineno >= 0; -- lineno) { + const linetext = document.lineAt(lineno).text; + const commentStartIndex = linetext.indexOf('/*'); + + if (commentStartIndex > -1 && (lineno < nearestFloatLine || commentEndIndex > commentStartIndex)) { + let clearLineText = linetext.substring(commentStartIndex + 2).trim(); + + if (lineno === nearestFloatLine) { + clearLineText = clearLineText.substring(0, clearLineText.indexOf('*/')); + } + + if (clearLineText.startsWith('*')) { + clearLineText = clearLineText.substring(1).trim(); + } + if (clearLineText.length > 0) { + comment = clearLineText + '\n\n' + comment; + } + break; + } else { + let clearLineText = linetext.trim(); + if (lineno === nearestFloatLine) { + clearLineText = clearLineText.substring(0, clearLineText.indexOf('*/')); + } + + if (clearLineText.startsWith('*')) { + clearLineText = clearLineText.substring(1).trim(); + } + + if (clearLineText.length > 0) { + comment = clearLineText + '\n\n' + comment; + } + } + } + + comment = comment.trim(); + if (comment.length > 0) { + comments.push(comment); + } + } + + } + } + + + + // 情况 2.1:单行注释 + if (currentText.includes('//')) { + const singleLineCommentStartIndex = currentText.indexOf('//'); + const comment = currentText.substring(singleLineCommentStartIndex + 2); + if (comment !== undefined && comment.length > 0) { + comments.push(comment); + } + } + + // 情况 2.2:多行注释 + if (currentText.includes('/*')) { + const commentStartIndex = currentText.indexOf('/*'); + let comment = ''; + for (let lineno = currentLine; lineno < document.lineCount; ++ lineno) { + const linetext = document.lineAt(lineno).text; + const commentEndIndex = linetext.indexOf('*/'); + if (commentEndIndex > -1 && (lineno > currentLine || commentEndIndex > commentStartIndex)) { + let clearLineText = linetext.substring(0, commentEndIndex).trim(); + + if (lineno === currentLine) { + clearLineText = clearLineText.substring(clearLineText.indexOf('/*') + 2).trim(); + } + + if (clearLineText.startsWith('*')) { + clearLineText = clearLineText.substring(1).trim(); + } + comment += clearLineText + '\n'; + break; + } else { + let clearLineText = linetext.trim(); + if (clearLineText.startsWith('*')) { + clearLineText = clearLineText.substring(1).trim(); + } + comment += clearLineText + '\n'; + } + } + + comment = comment.trim(); + if (comment.length > 0) { + comments.push(comment); + } + } + + return comments; +} + +function getFullSymbolInfoVhdl() { + const comments = []; + +} + async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, nonblank: RegExp, l_comment_symbol: string, l_comment_regExp: RegExp): Promise { const comments = []; + if (document.languageId !== 'vhdl') { + comments.push(...getFullSymbolInfoVlog(document, range)); + let resultComment = ''; + for (const c of comments.reverse()) { + resultComment += c.trim() + '\n'; + } + + return resultComment; + } + + let content = ''; let is_b_comment = false; - let line = range.start.line; + let line = range.start.line + 1; // vscode 的行编号从 0 开始算 - const firstLine = range.start.line - 1; + const firstLine = range.start.line - 1; while (line) { line --; content = document.lineAt(line).text; + LspOutput.report(content); // 首先判断该行是否是空白 if (content.trim().length === 0) { diff --git a/src/function/sim/simulate.ts b/src/function/sim/simulate.ts index bed163c..339d062 100644 --- a/src/function/sim/simulate.ts +++ b/src/function/sim/simulate.ts @@ -9,6 +9,7 @@ import { getSelectItem } from './instance'; import { ToolChainType } from '../../global/enum'; import { HdlModule } from '../../hdlParser/core'; import { Path } from '../../../resources/hdlParser'; +import { ModuleDataItem } from '../treeView/tree'; interface SimulateConfig { mod : string, // 设置的顶层模块 @@ -84,7 +85,7 @@ class Simulate { const setting = vscode.workspace.getConfiguration(); // make simulation dir - const defaultSimulationDir = hdlPath.join(opeParam.prjInfo.arch.prjPath, 'simulation', 'icarus'); + const defaultSimulationDir = hdlPath.join(opeParam.prjInfo.arch.prjPath, 'icarus'); simConfig.simulationHome = setting.get('digital-ide.function.simulate.simulationHome', ''); if (!fs.existsSync(simConfig.simulationHome)) { simConfig.simulationHome = defaultSimulationDir; @@ -357,33 +358,24 @@ class IcarusSimulate extends Simulate { this.simulateByHdlModule(hdlModule); } - public async simulateFile() { - const editor = vscode.window.activeTextEditor; - if (!editor) { + public async simulateFile(view: ModuleDataItem) { + if (!view.path) { + MainOutput.report('module ' + view.name + ' is not a hdlFile', ReportType.Error, true); return; } - const uri = editor.document.uri; - const path = hdlPath.toSlash(uri.fsPath); - const currentFile = hdlParam.getHdlFile(path); + const currentFile = hdlParam.getHdlFile(view.path); if (!currentFile) { - MainOutput.report('path ' + path + ' is not a hdlFile', ReportType.Error, true); + MainOutput.report('path ' + view.path + ' is not a hdlFile', ReportType.Error, true); return; } - const items = getSelectItem(currentFile.getAllHdlModules()); - if (items.length) { - let selectModule: HdlModule; - if (items.length === 1) { - selectModule = items[0].module; - } else { - const select = await vscode.window.showQuickPick(items, {placeHolder: 'choose a top module'}); - if (select) { - selectModule = select.module; - } else { - return; - } - } - this.simulateByHdlModule(selectModule); + + const targetModule = currentFile.getAllHdlModules().filter(mod => mod.name === view.name)[0]; + if (targetModule !== undefined) { + this.simulateByHdlModule(targetModule); + } else { + MainOutput.report('There is no module named ' + view.name + ' in ' + view.path, ReportType.Error, true); + return; } } } @@ -395,8 +387,8 @@ namespace Icarus { await icarus.simulateModule(hdlModule); } - export async function simulateFile() { - await icarus.simulateFile(); + export async function simulateFile(view: ModuleDataItem) { + await icarus.simulateFile(view); } }; diff --git a/src/function/treeView/command.ts b/src/function/treeView/command.ts index b1f69ab..facf5e1 100644 --- a/src/function/treeView/command.ts +++ b/src/function/treeView/command.ts @@ -200,10 +200,19 @@ class ToolTreeProvider extends BaseCommandTreeProvider { // remove prjPath & .xil const prjPath = opeParam.prjInfo.arch.prjPath; + const xilFolder = hdlPath.join(workspacePath, '.Xil'); - hdlDir.rmdir(prjPath); - hdlDir.rmdir(xilFolder); + + if (prjPath !== opeParam.workspacePath) { + hdlDir.rmdir(prjPath); + hdlDir.rmdir(xilFolder); + MainOutput.report("remove dir : " + prjPath); + MainOutput.report("remove dir : " + xilFolder); + } else { + vscode.window.showWarningMessage("arch.prjPath is the same as the workspace path, the clean will delete the project, please check your arch.prjPath!"); + } + // move bd * ip const plName = opeParam.prjInfo.prjName.PL; const targetPath = fspath.dirname(opeParam.prjInfo.arch.hardware.src); @@ -211,13 +220,16 @@ class ToolTreeProvider extends BaseCommandTreeProvider { const sourceBdPath = `${workspacePath}/prj/xilinx/${plName}.srcs/sources_1/bd`; hdlDir.mvdir(sourceIpPath, targetPath, true); + MainOutput.report("move dir from " + sourceIpPath + " to " + targetPath); + hdlDir.mvdir(sourceBdPath, targetPath, true); + MainOutput.report("move dir from " + sourceBdPath + " to " + targetPath); const ignores = hdlIgnore.getIgnoreFiles(); - const strFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.str')); for (const path of strFiles) { hdlFile.removeFile(path); + MainOutput.report("remove file " + path); } const logFiles = hdlFile.pickFileRecursive(workspacePath, ignores, p => p.endsWith('.log')); diff --git a/src/function/treeView/tree.ts b/src/function/treeView/tree.ts index ca00a89..718c538 100644 --- a/src/function/treeView/tree.ts +++ b/src/function/treeView/tree.ts @@ -14,7 +14,7 @@ interface ModuleDataItem { icon: string, // 图标 name: string, // module name type: string, - range: Range | null, + range: Range | undefined | null, path: AbsPath | undefined, // path of the file parent: ModuleDataItem | null // parent file } @@ -213,18 +213,19 @@ class ModuleTreeProvider implements vscode.TreeDataProvider { if (!element.path) { return []; } - + const moduleDataItemList: ModuleDataItem[] = []; const targetModule = hdlParam.getHdlModule(element.path, element.name); if (targetModule) { for (const instance of targetModule.getAllInstances()) { + // 所有的例化模块都定向到它的定义文件上 const item: ModuleDataItem = { icon: 'file', type: instance.name, name: instance.type, - range: instance.range, - path: instance.parentMod.path, + range: instance.module?.range, + path: instance.module?.path, parent: element }; diff --git a/src/global/prjInfo.ts b/src/global/prjInfo.ts index 8602801..65bd3f8 100644 --- a/src/global/prjInfo.ts +++ b/src/global/prjInfo.ts @@ -9,6 +9,8 @@ import { ToolChainType, LibraryState, XilinxIP, import { PrjInfoSchema } from './propertySchema'; import assert = require('assert'); import * as hdlPath from '../hdlFs/path'; +import { hdlDir } from '../hdlFs'; +import { MainOutput } from './outputChannel'; type AbsPath = string; @@ -265,7 +267,9 @@ class PrjInfo implements PrjInfoMeta { if (fs.existsSync(uniformPath)) { return uniformPath; } else { - vscode.window.showErrorMessage('path ' + uniformPath + ' not exist!'); + hdlDir.mkdir(uniformPath); + MainOutput.report("create dir: " + uniformPath); + // vscode.window.showErrorMessage('path ' + uniformPath + ' not exist!'); return undefined; } } else { diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index bae374d..4546ae8 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -248,11 +248,11 @@ class HdlParam { } public async initialize(hdlFiles: AbsPath[] | Generator) { - // await this.initHdlFiles(hdlFiles); + await this.initHdlFiles(hdlFiles); - // for (const hdlFile of this.getAllHdlFiles()) { - // hdlFile.makeInstance(); - // } + for (const hdlFile of this.getAllHdlFiles()) { + hdlFile.makeInstance(); + } } public getTopModulesByType(type: string): HdlModule[] { diff --git a/src/manager/libPick.ts b/src/manager/libPick.ts index 2b31a39..7cbe6cf 100644 --- a/src/manager/libPick.ts +++ b/src/manager/libPick.ts @@ -7,6 +7,7 @@ import { PrjInfo, RawPrjInfo } from '../global/prjInfo'; import { HdlLangID } from '../global/enum'; import { hdlFile, hdlPath } from '../hdlFs'; import { getIconConfig } from '../hdlFs/icons'; +import { getLanguageId } from '../hdlFs/file'; type MissPathType = { path?: string }; type LibPickItem = vscode.QuickPickItem & MissPathType; @@ -76,14 +77,14 @@ class LibPick { } private getReadmeText(path: AbsPath, fileName: string): string | undefined { - const mdPath1 = hdlPath.join(path, fileName, 'readme.md'); - if (fs.existsSync(mdPath1)) { - return hdlFile.readFile(mdPath1); - } - const mdPath2 = hdlPath.join(path, fileName, 'README.md'); - if (fs.existsSync(mdPath2)) { - return hdlFile.readFile(mdPath2); + const allowReadmeFile = ['readme.md', 'README.md', 'readme', 'README', 'readme.txt'] + for (const readmeFile of allowReadmeFile) { + const mdpath = hdlPath.join(path, fileName, readmeFile); + if (fs.existsSync(mdpath)) { + return hdlFile.readFile(mdpath); + } } + return undefined; } @@ -96,14 +97,32 @@ class LibPick { items.push(this.backQuickPickItem); } - for (const fileName of fs.readdirSync(path)) { + for (const fileName of fs.readdirSync(path)) { const filePath = hdlPath.join(path, fileName); - const themeIcon = this.getPathIcon(filePath); - const label = themeIcon + " " + fileName; - const mdText = this.getReadmeText(path, fileName); - const description = mdText ? mdText : ''; - const buttons = [{iconPath: getIconConfig('import'), tooltip: 'import everything in ' + fileName}]; - items.push({label, description, path: filePath, buttons}); + if (hdlFile.isFile(filePath)) { + const fileLangId = getLanguageId(filePath); + if (fileLangId === HdlLangID.Unknown) { + // 不是 hdl 直接跳过 + continue; + } + + const themeIcon = this.getPathIcon(filePath); + const label = themeIcon + " " + fileName; + const buttons = [{iconPath: getIconConfig('import'), tooltip: 'import everything in ' + fileName}]; + items.push({label, description: '', path: filePath, buttons}); + } else if (hdlFile.isDir(filePath)) { + if (['.git', '.github', '.vscode'].includes(fileName)) { + continue; + } + const themeIcon = this.getPathIcon(filePath); + const label = themeIcon + " " + fileName; + // 寻找 fileName 下的 readme,fileName 在这里是一个 文件夹 + const mdText = this.getReadmeText(path, fileName); + const description = mdText ? mdText : ''; + const buttons = [{iconPath: getIconConfig('import'), tooltip: 'import everything in ' + fileName}]; + items.push({label, description, path: filePath, buttons}); + } + } return items; }