⚡ 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,17 +1,20 @@
import type { WrittenBlock } from './testBlocks'
import type { BlockView } from './types'
import { describe, expect, it } from 'vitest'
import { coveredByEditing, startEditing } from './editing'
import { placementOf } from './placement'
import { revealPlan, uncoveredPlan } from './reveal'
import { placed } from './testBlocks'
function block(id: string, kind: string, [startLine, endLine]: [number, number], children: BlockView[] = []): BlockView {
return { id, kind, startLine, endLine, attributes: { kind }, concepts: [{ id: kind, label: kind, icon: 'box' }], children, properties: [] }
function block(id: string, kind: string, lines: [number, number], children: WrittenBlock[] = []): WrittenBlock {
return { id, anchor: id, kind, lines, attributes: { kind }, concepts: [{ id: kind, label: kind, icon: 'box' }], children, properties: [] }
}
/**
* 编辑范围是块的完整源码:库规则的卡片(1)是整个类(2–12 行),两个字段中间写着的方法(1.0)和它的主体(1.0.0)、
* 类末尾的方法(1.1)都在这段里;普通的类(2)同样盖住它的方法(2.0);`} else {` 写在一行时 if(3)和 else(4)共用第 20 行。
*/
const BLOCKS = [
const BLOCKS = placed([
block('0', 'import', [0, 0]),
block('1', 'sqlalchemy.table', [2, 12], [
block('1.0', 'function', [5, 6], [block('1.0.0', 'return', [6, 6])]),
@@ -20,7 +23,8 @@ const BLOCKS = [
block('2', 'class', [14, 16], [block('2.0', 'function', [15, 16])]),
block('3', 'if', [18, 20], [block('3.0', 'return', [19, 19])]),
block('4', 'else', [20, 22], [block('4.0', 'return', [21, 21])]),
]
])
const PLACEMENT = placementOf(BLOCKS)
describe('同一行不会同时在两处能改', () => {
it('块编辑时它的子孙都不画(代码都在它的编辑框里),跳到它们时改闪它', () => {
@@ -38,29 +42,31 @@ describe('同一行不会同时在两处能改', () => {
})
it('点「编辑」:编辑范围和它重叠的别的块(祖先、子孙、共用一行的兄弟块)退出编辑,不重叠的留着', () => {
expect(startEditing(BLOCKS, ['1.0', '1.1', '2'], '1')).toEqual(['2', '1'])
expect(startEditing(BLOCKS, ['1', '2'], '1.0')).toEqual(['2', '1.0'])
expect(startEditing(BLOCKS, ['2'], '2.0')).toEqual(['2.0'])
expect(startEditing(BLOCKS, ['0', '3'], '4')).toEqual(['0', '4'])
expect(startEditing(PLACEMENT, ['1.0', '1.1', '2'], '1')).toEqual(['2', '1'])
expect(startEditing(PLACEMENT, ['1', '2'], '1.0')).toEqual(['2', '1.0'])
expect(startEditing(PLACEMENT, ['2'], '2.0')).toEqual(['2.0'])
expect(startEditing(PLACEMENT, ['0', '3'], '4')).toEqual(['0', '4'])
})
it('任何时候正在编辑、画出来的几块,编辑范围两两不重叠', () => {
const all = (list: BlockView[]): BlockView[] => list.flatMap(item => [item, ...all(item.children)])
let editing: string[] = []
for (const id of ['1.0', '1.0.0', '2', '2.0', '1', '3.0', '3', '4', '1.1'])
editing = startEditing(BLOCKS, editing, id)
editing = startEditing(PLACEMENT, editing, id)
const covered = coveredByEditing(BLOCKS, new Set(editing))
const shown = all(BLOCKS).filter(item => editing.includes(item.id) && !covered.has(item.id))
for (const a of shown) {
for (const b of shown.filter(other => other !== a))
expect(a.startLine > b.endLine || b.startLine > a.endLine, `${a.id} / ${b.id}`).toBe(true)
for (const b of shown.filter(other => other !== a)) {
const [x, y] = [PLACEMENT.of(a.id)!, PLACEMENT.of(b.id)!]
expect(x.line > y.endLine || y.line > x.endLine, `${a.id} / ${b.id}`).toBe(true)
}
}
})
it('跳到定义的目标被盖住:闪盖住它的那块,展开那块的祖先', () => {
const covered = coveredByEditing(BLOCKS, new Set(['1']))
expect(uncoveredPlan({ id: '1.0.0', expand: ['1', '1.0'] }, covered)).toEqual({ id: '1', expand: [] })
const plain = revealPlan(BLOCKS, 15, 999)
const plain = revealPlan(BLOCKS, PLACEMENT, 15, 999)
expect(plain && uncoveredPlan(plain, covered)).toEqual(plain)
})
})