6.9 KiB
6.9 KiB
文档页面开发记录
文档页面实现功能
-
文档分页获取文件为markdown格式 代码示例
```html <!-- webview\src\components\DocCodePanel.vue --> <template> <MarkdownViewer :file-path="filePath"/> </template> <script> // 文档路径 // const filePath = ref('__localWebViewPath/ruanjian.md') const filePath = ref('__localWorkspacePath/ruanjian.md') </script> ```
- 文件支持的路径及修改方式
- 支持插件自身目录
filePath的值以
__localWebViewPath/
开头 - 支持工作区目录
filePath的值以
__localWorkspacePath/
开头
- 支持插件自身目录
filePath的值以
- 文件支持的路径及修改方式
-
- 左侧为标题目录
- 支持折叠展开
- 支持点击时 右侧文档滚动到对应位置
- 右侧为文档主题
-
支持展示图片
-
支持特殊标记实现点击时打开工作区内文件中的某个函数 目前暂定格式与示例
示例: 打开vscode中的src/test.js:testFunction 格式: 显示文字 关键代码:///webview\src\components\MarkdownViewer.vue /// ... const renderLink = renderer.link const handleDelegateClick = (event) => { // 通过事件冒泡捕获目标元素 const target = event.target.closest('.openFileAndGoToFunction') if (target) { const { filepath, functionname } = target.dataset console.log(filepath, functionname, '_**=== filepath, functionname'); console.log(target.dataset, '_**=== target.dataset'); if (window.acquireVsCodeApi && window.vscodeApi) { window.vscodeApi.postMessage({ type: 'openFileAndGoToFunction', filePath: filepath, functionName: functionname }); } } } renderer.link = function (src) { // 工作区跳转 if (src.href.startsWith("__workspace/")) { const { href, title, tokens } = src const text = renderer.parser.parseInline(tokens); // const cleanHref = cleanUrl(href); const titleTip = href.slice("__workspace/".length); const [filePath, functionName] = titleTip.split('?functionName=') console.log(filePath, functionName, '_**=== filePath, functionName'); return `<a href="javascript:void 0" class="openFileAndGoToFunction" title="点击打开关联文件函数: ${titleTip}" data-href="${href}" data-filepath="${filePath}" data-functionname="${functionName}">${text}</a>` } return renderLink.call(renderer, src); }
// src\extension\ChatViewProvider.ts async openFileAndGoToFunction(message: ListenerParam): Promise<void | false> { if (message.type !== 'openFileAndGoToFunction') { return false }; const rootUri = vscode.workspace.workspaceFolders?.[0]?.uri; const filePath = message.filePath; // 确保路径正确,相对于工作区 this._logger(rootUri + '#####' + filePath) const targetFunc = message.functionName if (!filePath || !targetFunc) { vscode.window.showWarningMessage(`未提供文件: ${filePath} 或函数: ${targetFunc}`) return } try { // 打开文件 const docInfo = await this.openWorkspaceFile(filePath); if (!docInfo) { vscode.window.showWarningMessage(`无法打开或创建文件: ${filePath}`) return } const { editor, document } = docInfo // 获取文档符号 const symbols = await vscode.commands.executeCommand<vscode.DocumentSymbol[]>( 'vscode.executeDocumentSymbolProvider', document.uri ) if (symbols) { const funcSymbol = this.findFunction(symbols, targetFunc) if (funcSymbol) { // 跳转到目标位置 editor.revealRange(funcSymbol.range, vscode.TextEditorRevealType.InCenter) editor.selection = new vscode.Selection(funcSymbol.range.start, funcSymbol.range.end) } else { vscode.window.showWarningMessage(`未找到函数 ${targetFunc}`) } } } catch (error) { vscode.window.showErrorMessage(`无法打开文件: ${error}`) } } // 打开工作区的文件 async openWorkspaceFile(relativePath: string) { // 1. 获取工作区根路径 const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri; if (!workspaceRoot) { vscode.window.showErrorMessage(" 未检测到工作区"); return; } // 2. 拼接完整路径(自动处理跨平台路径) const targetUri = vscode.Uri.joinPath(workspaceRoot, relativePath); // 3. 文件存在性检测 try { await vscode.workspace.fs.stat(targetUri); } catch { const createNew = await vscode.window.showInformationMessage( "文件不存在,是否创建?", "创建", "取消" ); if (createNew === "创建") { await vscode.workspace.fs.writeFile(targetUri, Buffer.from("")); } else { return; } } this._logger(targetUri + ':::targetUri') // 4. 打开文件编辑器 const document = await vscode.workspace.openTextDocument(targetUri); const editor = await vscode.window.showTextDocument(document); return { document, editor } }
-
- 左侧为标题目录
-
插件信息与修改: 若需要改为标题或列表, 修改 renderer 的对应方法以及触发跳转, 渲染的元素添加类名