Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
59a7854aa3 | |||
f79d071b48 | |||
58682bfb4d |
BIN
doc/image-1.png
Normal file
BIN
doc/image-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
BIN
doc/image.png
Normal file
BIN
doc/image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
154
doc/文档tab页.md
Normal file
154
doc/文档tab页.md
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
# 文档页面开发记录
|
||||||
|
|
||||||
|
## 文档页面实现功能
|
||||||
|
1. 文档分页获取文件为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>
|
||||||
|
```
|
||||||
|
- 文件支持的路径及修改方式
|
||||||
|
1. 支持插件自身目录
|
||||||
|
filePath的值以 `__localWebViewPath/` 开头
|
||||||
|
2. 支持工作区目录
|
||||||
|
filePath的值以 `__localWorkspacePath/` 开头
|
||||||
|
|
||||||
|
|
||||||
|
2. 布局:
|
||||||
|

|
||||||
|
- 左侧为标题目录
|
||||||
|
1. 支持折叠展开
|
||||||
|
1. 支持点击时 右侧文档滚动到对应位置
|
||||||
|
- 右侧为文档主题
|
||||||
|
1. 支持展示图片
|
||||||
|
1. 支持特殊标记实现点击时打开工作区内文件中的某个函数
|
||||||
|
目前暂定格式与示例\
|
||||||
|
示例:
|
||||||
|
[打开vscode中的src/test.js:testFunction](__workspace/src/test.js?functionName=resolveTripleslashReference)
|
||||||
|
格式:
|
||||||
|
[显示文字](__workspace/[文件的相对路径]?functionName=[函数名])
|
||||||
|
关键代码:
|
||||||
|
``` js
|
||||||
|
///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);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 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 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
1. 插件信息与修改: 若需要改为标题或列表, 修改 renderer 的对应方法以及触发跳转, 渲染的元素添加类名
|
||||||
|
|
||||||
|
[marked使用文档](https://marked.nodejs.cn/using_pro#hooks)
|
||||||
|

|
@ -9,7 +9,7 @@ function log(message: string) {
|
|||||||
if (!outputChannel) {
|
if (!outputChannel) {
|
||||||
outputChannel = vscode.window.createOutputChannel('AI Chat Plugin');
|
outputChannel = vscode.window.createOutputChannel('AI Chat Plugin');
|
||||||
}
|
}
|
||||||
|
|
||||||
const timestamp = new Date().toISOString();
|
const timestamp = new Date().toISOString();
|
||||||
outputChannel.appendLine(`[${timestamp}] ${message}`);
|
outputChannel.appendLine(`[${timestamp}] ${message}`);
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
// 创建输出通道
|
// 创建输出通道
|
||||||
outputChannel = vscode.window.createOutputChannel('AI Chat Plugin');
|
outputChannel = vscode.window.createOutputChannel('AI Chat Plugin');
|
||||||
outputChannel.show(true);
|
outputChannel.show(true);
|
||||||
|
|
||||||
log('VSCode AI Chat Plugin 已激活');
|
log('VSCode AI Chat Plugin 已激活');
|
||||||
|
|
||||||
// 注册Webview视图提供程序
|
// 注册Webview视图提供程序
|
||||||
@ -37,7 +37,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
vscode.commands.executeCommand('workbench.view.extension.aiChatView');
|
vscode.commands.executeCommand('workbench.view.extension.aiChatView');
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
// 监听配置变更
|
// 监听配置变更
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
vscode.workspace.onDidChangeConfiguration(e => {
|
vscode.workspace.onDidChangeConfiguration(e => {
|
||||||
@ -50,8 +50,8 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
export function deactivate() {
|
export function deactivate() {
|
||||||
log('VSCode AI Chat Plugin 已停用');
|
log('VSCode AI Chat Plugin 已停用');
|
||||||
|
|
||||||
if (outputChannel) {
|
if (outputChannel) {
|
||||||
outputChannel.dispose();
|
outputChannel.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -486,34 +486,38 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
|
|||||||
}
|
}
|
||||||
findFunction(symbols: vscode.DocumentSymbol[], name: string): vscode.DocumentSymbol | false {
|
findFunction(symbols: vscode.DocumentSymbol[], name: string): vscode.DocumentSymbol | false {
|
||||||
for (const symbol of symbols) {
|
for (const symbol of symbols) {
|
||||||
if (symbol.kind === vscode.SymbolKind.Function && symbol.name === name) {
|
if (symbol.kind === vscode.SymbolKind.Function && symbol.name === name) {
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
if (symbol.children) {
|
if (symbol.children) {
|
||||||
const found = this.findFunction(symbol.children, name);
|
const found = this.findFunction(symbol.children, name);
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
async openFileAndGoToFunction(message: ListenerParam): Promise<void | false> {
|
async openFileAndGoToFunction(message: ListenerParam): Promise<void | false> {
|
||||||
if (message.type !== 'openFileAndGoToFunction') { return false };
|
if (message.type !== 'openFileAndGoToFunction') { return false };
|
||||||
const filePath = message.filePath; // 确保路径正确,可以是绝对路径或相对于工作区
|
const rootUri = vscode.workspace.workspaceFolders?.[0]?.uri;
|
||||||
|
const filePath = message.filePath; // 确保路径正确,相对于工作区
|
||||||
|
this._logger(rootUri + '#####' + filePath)
|
||||||
const targetFunc = message.functionName
|
const targetFunc = message.functionName
|
||||||
if (!filePath || !targetFunc){
|
if (!filePath || !targetFunc) {
|
||||||
vscode.window.showWarningMessage(`未提供文件: ${filePath} 或函数: ${targetFunc}`)
|
vscode.window.showWarningMessage(`未提供文件: ${filePath} 或函数: ${targetFunc}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 打开文件
|
// 打开文件
|
||||||
const uri = vscode.Uri.file(filePath)
|
const docInfo = await this.openWorkspaceFile(filePath);
|
||||||
const doc = await vscode.workspace.openTextDocument(uri)
|
if (!docInfo) {
|
||||||
const editor = await vscode.window.showTextDocument(doc)
|
vscode.window.showWarningMessage(`无法打开或创建文件: ${filePath}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { editor, document } = docInfo
|
||||||
// 获取文档符号
|
// 获取文档符号
|
||||||
const symbols = await vscode.commands.executeCommand<vscode.DocumentSymbol[]>(
|
const symbols = await vscode.commands.executeCommand<vscode.DocumentSymbol[]>(
|
||||||
'vscode.executeDocumentSymbolProvider',
|
'vscode.executeDocumentSymbolProvider',
|
||||||
doc.uri
|
document.uri
|
||||||
)
|
)
|
||||||
|
|
||||||
if (symbols) {
|
if (symbols) {
|
||||||
@ -534,7 +538,23 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
|
|||||||
fetchMdFile(message: ListenerParam, webview: WebviewViewIns): false | void {
|
fetchMdFile(message: ListenerParam, webview: WebviewViewIns): false | void {
|
||||||
if (message.type !== 'loadMd') { return false }
|
if (message.type !== 'loadMd') { return false }
|
||||||
if (message.mdPath) {
|
if (message.mdPath) {
|
||||||
const filePath = path.join(this._extensionUri.fsPath, 'webview', 'dist', message.mdPath!.replace('__localWebViewPath/', ''))
|
let filePath
|
||||||
|
const isFromWorkspace = message.mdPath.startsWith('__localWorkspacePath/')
|
||||||
|
if (isFromWorkspace) {
|
||||||
|
// 1. 获取工作区根路径
|
||||||
|
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri;
|
||||||
|
if (!workspaceRoot) {
|
||||||
|
vscode.window.showErrorMessage(" 未检测到工作区");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 拼接完整路径(自动处理跨平台路径)
|
||||||
|
filePath = vscode.Uri.joinPath(workspaceRoot, message.mdPath.replace('__localWorkspacePath/', '')).fsPath;
|
||||||
|
// filePath = path.join(workspaceRoot.toString(), message.mdPath.replace('__localWorkspacePath/', ''))
|
||||||
|
} else {
|
||||||
|
filePath = path.join(this._extensionUri.fsPath, 'webview', 'dist', message.mdPath.replace('__localWebViewPath/', ''))
|
||||||
|
}
|
||||||
|
this._logger(filePath + '::: 当前md路径')
|
||||||
try {
|
try {
|
||||||
const content = fs.readFileSync(filePath, 'utf-8')
|
const content = fs.readFileSync(filePath, 'utf-8')
|
||||||
webview.postMessage({ type: 'mdContent', data: content })
|
webview.postMessage({ type: 'mdContent', data: content })
|
||||||
@ -546,4 +566,36 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
|
|||||||
}
|
}
|
||||||
webview.postMessage({ type: 'mdContent', data: '未正确传入md文件路径' })
|
webview.postMessage({ type: 'mdContent', data: '未正确传入md文件路径' })
|
||||||
}
|
}
|
||||||
}
|
// 打开工作区的文件
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
}
|
@ -37,4 +37,9 @@
|
|||||||
- **快速主题与滤镜**
|
- **快速主题与滤镜**
|
||||||
- 全局主题与滤镜:支持全局主题设置,用户可以一键切换不同的主题风格,包括颜色、字体、背景等元素,快速调整数据可视化的整体视觉效果。同时,提供滤镜功能,用户可以对图表进行美化处理,如添加阴影、渐变色等效果,提升数据可视化的美观度。
|
- 全局主题与滤镜:支持全局主题设置,用户可以一键切换不同的主题风格,包括颜色、字体、背景等元素,快速调整数据可视化的整体视觉效果。同时,提供滤镜功能,用户可以对图表进行美化处理,如添加阴影、渐变色等效果,提升数据可视化的美观度。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
示例:
|
||||||
|
[打开vscode中的src/test.js:testFunction](__workspace/src/test.js?functionName=resolveTripleslashReference)
|
||||||
|
格式:
|
||||||
|
[显示文字](__workspace/[文件的相对路径]?functionName=[函数名])
|
@ -11,11 +11,14 @@
|
|||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import Header from './Header.vue';
|
import Header from './Header.vue';
|
||||||
import MarkdownViewer from './MarkdownViewer.vue';
|
import MarkdownViewer from './MarkdownViewer.vue';
|
||||||
// 输入框的值
|
// 文档路径
|
||||||
const filePath = ref('__localWebViewPath/ruanjian.md')
|
// const filePath = ref('__localWebViewPath/ruanjian.md')
|
||||||
if(!window.acquireVsCodeApi){
|
const filePath = ref('__localWorkspacePath/ruanjian.md')
|
||||||
filePath.value = '/ruanjian.md'
|
// if(!window.acquireVsCodeApi){
|
||||||
}
|
// filePath.value = '/ruanjian.md'
|
||||||
|
// }
|
||||||
|
/*
|
||||||
|
//#region 支持ws请求大模型获取doc文档
|
||||||
if(window.vscodeApi){
|
if(window.vscodeApi){
|
||||||
window.vscodeApi.postMessage({
|
window.vscodeApi.postMessage({
|
||||||
type: 'ws:connect',
|
type: 'ws:connect',
|
||||||
@ -49,6 +52,8 @@ if(window.vscodeApi){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//#endregion
|
||||||
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
<h2>目录</h2>
|
<h2>目录</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="toc-content">
|
<div class="toc-content">
|
||||||
<MDOutlineTree :data="tocTreeData"/>
|
<MDOutlineTree :data="tocTreeData" />
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- 主内容区域 -->
|
<!-- 主内容区域 -->
|
||||||
<main class="content" ref="content">
|
<main class="content" ref="content" @click="handleDelegateClick">
|
||||||
<div v-if="loading" class="loading-indicator">加载中...</div>
|
<div v-if="loading" class="loading-indicator">加载中...</div>
|
||||||
<div v-else-if="error" class="error-message">{{ error }}</div>
|
<div v-else-if="error" class="error-message">{{ error }}</div>
|
||||||
<div v-else v-html="renderedContent" class="markdown-content"></div>
|
<div v-else v-html="renderedContent" class="markdown-content"></div>
|
||||||
@ -74,9 +74,9 @@ renderer.heading = ({ text, depth }) => {
|
|||||||
toc.value.push({
|
toc.value.push({
|
||||||
id: escapedText,
|
id: escapedText,
|
||||||
level: depth,
|
level: depth,
|
||||||
title: text,
|
title: text,
|
||||||
anchor: escapedText
|
anchor: escapedText
|
||||||
})
|
})
|
||||||
const node = {
|
const node = {
|
||||||
key: escapedText,
|
key: escapedText,
|
||||||
title: text
|
title: text
|
||||||
@ -106,11 +106,61 @@ renderer.heading = ({ text, depth }) => {
|
|||||||
${text}
|
${text}
|
||||||
</h${depth}>`;
|
</h${depth}>`;
|
||||||
};
|
};
|
||||||
let renderList = renderer.listitem
|
// 渲染列表
|
||||||
|
const renderList = renderer.listitem
|
||||||
renderer.listitem = (src)=>{
|
// 若需改为列表跳转, 可改此函数
|
||||||
|
renderer.listitem = (src) => {
|
||||||
return renderList.call(renderer, src);
|
return renderList.call(renderer, src);
|
||||||
}
|
}
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderLink = renderer.link
|
||||||
|
renderer.link = function (src) {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"type": "link",
|
||||||
|
"raw": "[打开vscode中的文件1](__workspace/)",
|
||||||
|
"href": "__workspace/",
|
||||||
|
"title": null,
|
||||||
|
"text": "打开vscode中的文件1",
|
||||||
|
"tokens": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"raw": "打开vscode中的文件1",
|
||||||
|
"text": "打开vscode中的文件1",
|
||||||
|
"escaped": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// 工作区跳转
|
||||||
|
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);
|
||||||
|
}
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
renderer,
|
renderer,
|
||||||
highlight: (code, lang) => {
|
highlight: (code, lang) => {
|
||||||
@ -135,9 +185,8 @@ const loadMarkdownFile = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = null;
|
error.value = null;
|
||||||
let fetchMdPms
|
let fetchMdPms
|
||||||
|
if (filePath.startsWith('__localWebViewPath/') || filePath.startsWith('__localWorkspacePath/')) {
|
||||||
if(filePath.startsWith('__localWebViewPath/')){
|
if (!window.vscodeApi) {
|
||||||
if(!window.vscodeApi){
|
|
||||||
console.error('获取__localWebViewPath的md文档时, 无法获取VSCode API')
|
console.error('获取__localWebViewPath的md文档时, 无法获取VSCode API')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -158,7 +207,7 @@ const loadMarkdownFile = async () => {
|
|||||||
markdownText.value = event.data.data
|
markdownText.value = event.data.data
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
fetchMdPms = fetch(props.filePath);
|
fetchMdPms = fetch(props.filePath);
|
||||||
const response = await fetchMdPms
|
const response = await fetchMdPms
|
||||||
if (!response.ok) throw new Error('无法加载Markdown文件');
|
if (!response.ok) throw new Error('无法加载Markdown文件');
|
||||||
@ -178,8 +227,6 @@ const loadMarkdownFile = async () => {
|
|||||||
|
|
||||||
// 渲染Markdown
|
// 渲染Markdown
|
||||||
const renderMarkdown = () => {
|
const renderMarkdown = () => {
|
||||||
console.log(markdownText.value);
|
|
||||||
|
|
||||||
toc.value = []; // 清空目录
|
toc.value = []; // 清空目录
|
||||||
renderedContent.value = marked(markdownText.value);
|
renderedContent.value = marked(markdownText.value);
|
||||||
// 等待DOM更新后初始化高亮
|
// 等待DOM更新后初始化高亮
|
||||||
@ -187,6 +234,7 @@ const renderMarkdown = () => {
|
|||||||
document.querySelectorAll('pre code').forEach(block => {
|
document.querySelectorAll('pre code').forEach(block => {
|
||||||
hljs.highlightElement(block);
|
hljs.highlightElement(block);
|
||||||
});
|
});
|
||||||
|
// 懒加载, todo 兼容跳转
|
||||||
// setupHeadingObservers();
|
// setupHeadingObservers();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -244,7 +292,7 @@ const handleResize = throttle(() => {
|
|||||||
}, props.debounceTime);
|
}, props.debounceTime);
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onBeforeMount(()=>{
|
onBeforeMount(() => {
|
||||||
loadMarkdownFile();
|
loadMarkdownFile();
|
||||||
})
|
})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -309,9 +357,11 @@ onUnmounted(() => {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc-content {
|
.toc-content {
|
||||||
height: calc(100vh - 200px);
|
height: calc(100vh - 200px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc-content ul {
|
.toc-content ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user