⚡ perf(vscode): 代码阅读预览发给页面的块只记相对位置:块在源码里占的地方记成离前一块多远、自己多长,块里名字的下标从块的开头算,页面从文件开头累加回文件里的位置、和扩展端打交道的地方都在一处换算;靠前改了代码,后面内容没变的块发过去一模一样,扩展端自己的块和发给页面的块分成两种类型

This commit is contained in:
cruldra committed 2026-10-13 16:32:18 +11:00
1 parent 3a2815c19c
commit ad5f559e92
43 files changed
+980 -424

No files matched your search

+12 -8
View File
@@ -19,6 +19,7 @@ import { FilterBar } from './FilterBar'
import { OverviewRuler } from './OverviewRuler'
import { pageLayout } from './pageLayout'
import { createPageStore } from './pageState'
import { NO_PLACEMENT, placementOf } from './placement'
import { chatOf, PATH_ASK_ANCHOR, sameChat } from './qa'
import { TextMarksContext } from './SegmentText'
import { shareUnchanged } from './sharing'
@@ -71,7 +72,7 @@ export function App(): ReactElement | null {
const rewrite = useRewrite()
const [page] = useState(() => createPageStore(viewState.get()))
/** 页面上文字的标记:这个文档版本的中文名(文档带来的,扩展端查到了再换)和单击高亮的名字;各段文字按自己那几段订阅 */
const [marks] = useState(() => createStore<TextMarks>({ names: new Map() }))
const [marks] = useState(() => createStore<TextMarks>({ names: new Map(), placement: NO_PLACEMENT }))
/** 页面重新加载前开着的调用树弹框:第一份文档到了,那块还在就重新打开;到之前记着的不动 */
const restoreCall = useRef(viewState.get().callTree)
/** 块树所在的页面内容:钉住卡片时在这里面量 */
@@ -79,11 +80,13 @@ export function App(): ReactElement | null {
/** 页面内容挂上时,卡片的位置从它量(pageLayout):筛选栏和它在同一次提交里画出来 */
const attachContent = useCallback((el: HTMLDivElement | null) => {
content.current = el
return el ? pageLayout.attach(el, document.querySelector<HTMLElement>('.cr-filter-bar')) : undefined
return el ? pageLayout.attach(el, document.querySelector<HTMLElement>('.cr-filter-bar'), () => page.get().placement) : undefined
}, [])
// 这一层重画了:同一段脚本里接着要量位置的(滚到某一行、跳到改动、滚到当前那一处)不能用重画前量的,先作废;放在它们前面
useLayoutEffect(() => pageLayout.invalidate())
const { doc, editing, folds, reveal, excluded, diff, onlyChanges, openCall, changes, collapsed, filter, covered, unshown, stops } = useStore(page, current => current)
const { doc, editing, folds, reveal, excluded, diff, onlyChanges, openCall, changes, collapsed, filter, covered, placement, unshown, stops } = useStore(page, current => current)
/** 眼下这一版文档里各块在文件里的位置:事件里读名字的下标时现取 */
const currentPlacement = useCallback(() => page.get().placement, [page])
const pathChat = useStore(qa.store, state => chatOf(state, PATH_ASK_ANCHOR), sameChat)
const qaAvailable = useStore(qa.store, state => state.available)
const qaSubject = useStore(qa.store, state => state.subject)
@@ -97,8 +100,8 @@ export function App(): ReactElement | null {
const revealed = useCallback(() => page.update({ reveal: null }), [page])
useScrollPosition(doc)
useReveal(doc, reveal, collapsed, unshown, covered, show, expand, revealed)
useDefinitionLinks(doc?.version)
const peek = useDefinitionPeek(doc?.version)
useDefinitionLinks(doc?.version, currentPlacement)
const peek = useDefinitionPeek(doc?.version, currentPlacement)
const sticky = useStickySettings()
useRepoLinks()
useRepoImages()
@@ -106,11 +109,12 @@ export function App(): ReactElement | null {
const occurrencePage = useMemo((): OccurrencePage | undefined => doc
? {
blocks: doc.blocks,
placement,
skip: id => unshown.has(id) || covered.has(id) || editing.includes(id),
collapsed,
expand,
}
: undefined, [doc, unshown, covered, editing, collapsed, expand])
: undefined, [doc, placement, unshown, covered, editing, collapsed, expand])
const occurrences = useOccurrences(doc?.version, doc?.translatorId, occurrencePage, marks)
/** 块树:状态是页面 store 里的 tree,动作改页面 store;整页一份,卡片拿到的回调一直是同一个 */
@@ -124,7 +128,7 @@ export function App(): ReactElement | null {
const leaving = current.editing.includes(id)
return {
focusId: leaving ? null : id,
editing: leaving ? current.editing.filter(other => other !== id) : startEditing(current.doc?.blocks ?? [], current.editing, id),
editing: leaving ? current.editing.filter(other => other !== id) : startEditing(current.placement, current.editing, id),
}
}),
onFocused: () => page.update({ focusId: null }),
@@ -150,7 +154,7 @@ export function App(): ReactElement | null {
// 和上一份内容一样的块还是原来的对象:没变的卡片不重画
const next = shareUnchanged(page.get().doc, msg)
const reopened = restoring && openingCall(next, restoring.anchor, restoring.entry)
marks.set(current => ({ ...current, names: nameMap(msg.names) }))
marks.set(current => ({ ...current, names: nameMap(msg.names), placement: placementOf(next.blocks) }))
page.update(current => ({
doc: next,
keep: keptWhileEditing(current.keep, current.editing),