⚡ 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

@@ -1,10 +1,12 @@
import type { Click, Highlight, ScrollPosition } from './occurrences'
import type { Placement } from './placement'
import type { TextMarks } from './SegmentText'
import type { Store } from './store'
import type { BlockView, Occurrence } from './types'
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { documentNameAt, PEEK_ATTRIBUTE } from './definitionPeek'
import { clickAction, KeyScroll, OccurrenceHighlight, occurrenceJumpKey, OccurrenceNavigation } from './occurrences'
import { nameOffset, NO_PLACEMENT } from './placement'
import { occurrencePlan } from './reveal'
import { useStore } from './store'
import { showInViewport } from './useReveal'
@@ -19,6 +21,8 @@ const NON_TEXT_INPUTS = new Set(['checkbox', 'radio', 'button', 'submit', 'reset
/** 用键盘跳到一处出现时要用的页面状态。 */
export interface OccurrencePage {
blocks: BlockView[]
/** 各块在文件里的位置:点中的名字、各处出现按它和文件里的下标对上 */
placement: Placement
/** 这块里的出现跳不到:被筛掉的、正在编辑的、被正在编辑的祖先盖住的 */
skip: (id: string) => boolean
/** 眼下折叠着的块、属性行和子行 */
@@ -27,16 +31,18 @@ export interface OccurrencePage {
expand: (ids: string[]) => void
}
function clickOf(event: MouseEvent): Click {
/** 一次点击的情况;点中的名字在文件里的下标按 placement 换算 */
function clickOf(event: MouseEvent, placement: Placement): Click {
const target = event.target instanceof Element ? event.target : null
const name = documentNameAt(target)
const offset = name ? nameOffset(name, placement) : undefined
const selection = window.getSelection()
return {
modified: event.metaKey || event.ctrlKey || event.altKey || event.shiftKey,
count: event.detail,
selecting: selection !== null && !selection.isCollapsed,
// 起了中文名的名字写的是中文名(定义处后面还跟着原名),筛选栏上写中文名
name: name?.dataset.offset === undefined ? undefined : { offset: Number(name.dataset.offset), text: name.dataset.name ?? name.textContent ?? '' },
name: !name || offset === undefined ? undefined : { offset, text: name.dataset.name ?? name.textContent ?? '' },
control: target?.closest(CONTROLS) != null,
}
}
@@ -122,7 +128,7 @@ export function useOccurrences(version: number | undefined, translatorId: string
keyScroll.forget()
}
const current = latestPage.current
const planOf = (occurrence: Occurrence): ReturnType<typeof occurrencePlan> => current && occurrencePlan(current.blocks, occurrence, current.skip)
const planOf = (occurrence: Occurrence): ReturnType<typeof occurrencePlan> => current && occurrencePlan(current.blocks, current.placement, occurrence, current.skip)
const target = current && occurrences.move(step, occurrence => planOf(occurrence) !== undefined)
const plan = target && planOf(target)
if (!current || !plan) {
@@ -135,7 +141,7 @@ export function useOccurrences(version: number | undefined, translatorId: string
setMoves(count => count + 1)
}
// 捕获阶段:赶在块里的按钮处理点击、折叠箭头换图标之前读出点在哪
const onClick = (event: MouseEvent): void => occurrences.click(clickAction(clickOf(event)))
const onClick = (event: MouseEvent): void => occurrences.click(clickAction(clickOf(event, latestPage.current?.placement ?? NO_PLACEMENT)))
moveFromButton.current = step => move(step, false)
// 任何键都照常交给 VS Code。能跳时,默认的 ⌘↓ / ⌘↑(Windows 是 ctrl)取消浏览器滚到底 / 滚到顶,但不停冒泡,命令还是收得到
const onKeyDown = (event: KeyboardEvent): void => {