✨ feat(vscode): 代码阅读预览按住 ⌘ / Ctrl 点名字跳到定义

This commit is contained in:
cruldra committed 2026-09-25 12:54:45 +08:00
1 parent e5db1a2e65
commit 4e146eb48f
20 files changed
+870 -60

No files matched your search

@@ -0,0 +1,63 @@
import type { DocumentMessage, Reveal } from './types'
import { useLayoutEffect } from 'react'
import { revealPlan, scrollTopToShow } from './reveal'
import { blockForLine } from './scrollPosition'
import { measureBlocks } from './useScrollPosition'
/** 让一块闪几下(codeReader.css 的 [data-flash]);正在闪的同一块再跳一次时从头闪。 */
function flash(el: HTMLElement): void {
const running = el.getAnimations().filter(animation => animation instanceof CSSAnimation)
if (running.length > 0) {
for (const animation of running)
animation.currentTime = 0
return
}
const onEnd = (event: AnimationEvent): void => {
if (event.target !== el)
return
el.removeAttribute('data-flash')
el.removeEventListener('animationend', onEnd)
}
el.addEventListener('animationend', onEnd)
el.setAttribute('data-flash', '')
}
/**
* 滚到 reveal 指的位置,处理完调 done:
* ① 从文本编辑器切过来(没有 definition):包含那一行的块顶到视口顶部,折叠着的不展开;
* ② 跳到定义:先展开把目标藏起来的块和属性行(expand 之后重新渲染,再进来一次),再把目标块滚进视口、闪几下。
*/
export function useReveal(
doc: DocumentMessage | null,
reveal: Reveal | null,
collapsed: readonly string[],
expand: (ids: string[]) => void,
done: () => void,
): void {
useLayoutEffect(() => {
if (!doc || !reveal)
return
if (reveal.definition === undefined) {
const top = blockForLine(measureBlocks(), reveal.line)?.top
if (top !== undefined)
window.scrollTo(0, top)
done()
return
}
const plan = revealPlan(doc.blocks, reveal.line, reveal.definition)
const hidden = plan?.expand.filter(id => collapsed.includes(id)) ?? []
if (hidden.length > 0) {
expand(hidden)
return
}
const el = 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)
if (top !== undefined)
window.scrollTo(0, top)
flash(el)
}
done()
}, [doc, reveal, collapsed, expand, done])
}