⚡ 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

+26 -3
View File
@@ -1,12 +1,15 @@
import type { FileAttribute } from '../attributes'
import type { BlockView } from '../blockView'
import type { PageCard } from '../editor/messages'
import type { ChangedBlock, DiffStats, RemovedBlock } from './blockDiff'
import type { DiffBase } from './diffBase'
import { pageCard, pageMarks, sourceLines } from '../editor/pageBlocks'
import { splitLines } from '../editText'
import { diffBlockTrees } from './blockDiff'
/** 删掉的一块(见 RemovedBlock),带上种类的名字:旧版本里才有的种类,新文件的筛选属性里查不到它叫什么。 */
export interface RemovedView extends RemovedBlock {
/** 删掉的一块(见 RemovedBlock)发给页面的样子:旧版本里它自己的内容(见 pageCard),带上种类的名字(旧版本里才有的种类,新文件的筛选属性里查不到它叫什么)。 */
export interface RemovedView extends Omit<RemovedBlock, 'block'> {
block: PageCard
kindName: string
}
@@ -49,6 +52,20 @@ function kindNames(attributes: readonly FileAttribute[]): Map<string, string> {
return new Map(attributes.find(attribute => attribute.id === 'kind')?.values.map(value => [value.id, value.name]))
}
/** 各块的开头(第一行的行首)在文件里的下标,按块的记号:卡片里要标的改动发给页面时从块的开头算(见 pageMarks) */
function blockStarts({ blocks, source }: SentDocument): Map<string, number> {
const lines = sourceLines(source)
const starts = new Map<string, number>()
const visit = (list: readonly BlockView[]): void => {
for (const block of list) {
starts.set(block.anchor, lines.start(block.startLine))
visit(block.children)
}
}
visit(blocks)
return starts
}
/** 按基准比出来的差异:基准里没有这个文件时整份是新文件,否则两棵块树比(见 diffBlockTrees)。 */
export function documentDiff(base: DiffBase, sent: SentDocument, old: { source: string, document: OldDocument } | null): DocumentDiff {
const common = { base: base.label, version: sent.version, lineCount: splitLines(sent.source).length }
@@ -56,7 +73,13 @@ export function documentDiff(base: DiffBase, sent: SentDocument, old: { source:
return { ...common, newFile: base.missing, blocks: {}, removed: [], stats: NO_CHANGES }
const { blocks, removed, stats } = diffBlockTrees({ blocks: old.document.blocks, source: old.source }, sent)
const kinds = kindNames(old.document.attributes)
return { ...common, blocks, removed: removed.map(item => ({ ...item, kindName: kinds.get(item.block.kind) ?? item.block.kind })), stats }
const starts = blockStarts(sent)
return {
...common,
blocks: Object.fromEntries(Object.entries(blocks).map(([anchor, changed]) => [anchor, changed.marks ? { ...changed, marks: pageMarks(changed.marks, starts.get(anchor) ?? 0) } : changed])),
removed: removed.map(item => ({ ...item, block: pageCard(item.block, 0), kindName: kinds.get(item.block.kind) ?? item.block.kind })),
stats,
}
}
/**