✨ 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

+17 -7
View File
@@ -1,8 +1,9 @@
import type { DocumentMessage, Reveal } from './types'
import { useLayoutEffect } from 'react'
import { blockPath } from './filter'
import { revealPlan, scrollTopToShow } from './reveal'
import { blockForLine } from './scrollPosition'
import { measureBlocks } from './useScrollPosition'
import { measureBlocks, pinnedHeight } from './useScrollPosition'
/** 让一块或属性表里的一行闪几下(codeReader.css 的 [data-flash]);正在闪的同一处再跳一次时从头闪。 */
function flash(el: HTMLElement): void {
@@ -24,13 +25,16 @@ function flash(el: HTMLElement): void {
/**
* 滚到 reveal 指的位置,处理完调 done:
* ① 从文本编辑器切过来(没有 definition):包含那一行的块顶到视口顶部,折叠着的不展开;
* ② 跳到定义:先展开把目标藏起来的块、属性行和子行(expand 之后重新渲染,再进来一次),再把目标(整块,或就是这处定义的属性行 / 子行)滚进视口、闪几下。
* ① 从文本编辑器切过来(没有 definition):包含那一行的块顶到视口顶部(筛选栏下面),折叠着的、被筛掉的不展开;
* ② 跳到定义:目标或它的祖先块被筛掉了,先临时露出这条路径(show);再展开把目标折叠住的块、属性行和子行(expand)——
* 每一步之后重新渲染、再进来一次;最后把目标(整块,或就是这处定义的属性行 / 子行)滚进视口、闪几下。
*/
export function useReveal(
doc: DocumentMessage | null,
reveal: Reveal | null,
collapsed: ReadonlySet<string>,
filtered: ReadonlySet<string>,
show: (ids: string[]) => void,
expand: (ids: string[]) => void,
done: () => void,
): void {
@@ -40,11 +44,16 @@ export function useReveal(
if (reveal.definition === undefined) {
const top = blockForLine(measureBlocks(), reveal.line)?.top
if (top !== undefined)
window.scrollTo(0, top)
window.scrollTo(0, top - pinnedHeight())
done()
return
}
const plan = revealPlan(doc.blocks, reveal.line, reveal.definition)
const path = plan ? blockPath(plan.id) : []
if (path.some(id => filtered.has(id))) {
show(path)
return
}
const hidden = plan?.expand.filter(id => collapsed.has(id)) ?? []
if (hidden.length > 0) {
expand(hidden)
@@ -55,11 +64,12 @@ export function useReveal(
const el = row ?? (plan && document.querySelector<HTMLElement>(`.cr-block[data-id="${plan.id}"]`))
if (el) {
const rect = el.getBoundingClientRect()
const top = scrollTopToShow({ top: rect.top + window.scrollY, bottom: rect.bottom + window.scrollY }, window.scrollY, window.innerHeight)
const pinned = pinnedHeight()
const top = scrollTopToShow({ top: rect.top + window.scrollY, bottom: rect.bottom + window.scrollY }, window.scrollY + pinned, window.innerHeight - pinned)
if (top !== undefined)
window.scrollTo(0, top)
window.scrollTo(0, top - pinned)
flash(el)
}
done()
}, [doc, reveal, collapsed, expand, done])
}, [doc, reveal, collapsed, filtered, show, expand, done])
}