✨ feat(vscode): 代码阅读预览顶部加块筛选栏

语言插件按和语言无关的 id 报块属性(通用的由宿主从 facts 推),翻译插件起名,webview 只按 id 筛;
筛选整个工作区共用、记在 workspaceState;JavaScript 不再显示「抽象:否」「仅类型:否」
This commit is contained in:
cruldra committed 2026-09-25 21:31:19 +08:00
1 parent 4eaf2ae11d
commit 1c7e31c51a
29 files changed
+1364 -319

No files matched your search

+14 -1
View File
@@ -1,6 +1,7 @@
import type { CustomTextEditorProvider, Disposable, TextDocument, TextDocumentShowOptions, Uri, WebviewPanel } from 'vscode'
import type { CodeReaderRegistry } from '../registry'
import type { TreeSitterRuntime } from '../runtime'
import type { BlockFilter } from './blockFilter'
import type { Definition } from './definitions'
import type { ExtensionToWebview, Reveal, WebviewToExtension } from './messages'
import { commands, Range, window, workspace, WorkspaceEdit } from 'vscode'
@@ -29,13 +30,14 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
private readonly extensionUri: Uri,
private readonly registry: CodeReaderRegistry,
private readonly runtime: TreeSitterRuntime,
private readonly filter: BlockFilter,
) {}
resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel): void {
panel.webview.options = { enableScripts: true, localResourceRoots: [webviewUiRoot(this.extensionUri)] }
panel.webview.html = webviewHtml(panel.webview, this.extensionUri, 'code-reader.html')
const key = document.uri.toString()
const preview = new Preview(document, panel, this, this.registry, this.runtime, this.reveals.get(key))
const preview = new Preview(document, panel, this, this.registry, this.runtime, this.filter, this.reveals.get(key))
this.reveals.delete(key)
this.previews.add(preview)
panel.onDidDispose(() => {
@@ -96,6 +98,7 @@ class Preview {
private readonly owner: PreviewEditorProvider,
private readonly registry: CodeReaderRegistry,
private readonly runtime: TreeSitterRuntime,
private readonly filter: BlockFilter,
/**
* 随下一份真正发出去的文档走、只走一次:新预览第一份文档要滚到的位置,或页面正在重新加载时收不到的 reveal。
* 之后页面因标签页切走重新加载,按 webview 自己记的位置恢复
@@ -112,6 +115,11 @@ class Preview {
if (e.document === document && e.contentChanges.length > 0)
this.schedulePush()
}),
// 页面没 ready 时收不到,等它 ready 再随第一份文档之前补发
filter.subscribe((excluded) => {
if (this.ready)
this.post({ type: 'filter', excluded })
}),
]
}
@@ -167,8 +175,13 @@ class Preview {
switch (msg.type) {
case 'ready':
this.ready = true
// 先于文档发:第一份文档按筛选画,不会先整份露出来再藏
this.post({ type: 'filter', excluded: this.filter.excluded })
await this.push()
return
case 'setFilter':
await this.filter.set(msg.excluded)
return
case 'edit':
await this.applyEdit(msg.startLine, msg.endLine, msg.text)
return