✨ feat(vscode): 代码阅读差异加「只看改动」(连着没变的块折成一条、按工作区记住)、上一处 / 下一处改动、右边缘总览条
This commit is contained in:
1 parent
707d85c324
commit
6120c85bc0
14 files changed
+533
-42
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import type { BlockView, DocumentDiff, RemovedView } from './types'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { diffTree, openedByDiff, removedTitle, statsParts } from './diffView'
|
||||
import { changeStops, diffTree, foldUnchanged, nextStop, openedByDiff, removedTitle, statsParts } from './diffView'
|
||||
|
||||
function block(id: string, anchor: string, children: BlockView[] = [], extra: Partial<BlockView> = {}): BlockView {
|
||||
return { id, anchor, kind: 'function', startLine: 0, endLine: 0, code: '', codeTokens: [], attributes: { kind: 'function' }, children, translation: [], ...extra } as BlockView
|
||||
@@ -69,3 +69,82 @@ describe('removedTitle', () => {
|
||||
expect(removedTitle(block('0', 'x', [], { kind: 'comment', translation: { markdown: '说明第一行\n第二行' } }))).toBe('说明第一行')
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 0 function a(修改)
|
||||
* 0.0 import(没变)
|
||||
* 0.1 return(修改,自己改了)
|
||||
* 0.2 return(没变)
|
||||
* 1 function b(没变)
|
||||
* 2 function c(没变)
|
||||
* 3 function d(新增,带子块 3.0)
|
||||
* 4 function e(没变)
|
||||
*/
|
||||
const TREE_BLOCKS = [
|
||||
block('0', 'a', [block('0.0', 'a0', [], { startLine: 1 }), block('0.1', 'a1', [], { startLine: 2, endLine: 2 }), block('0.2', 'a2', [], { startLine: 3 })], { startLine: 0, endLine: 3 }),
|
||||
block('1', 'b', [], { startLine: 5 }),
|
||||
block('2', 'c', [], { startLine: 7 }),
|
||||
block('3', 'd', [block('3.0', 'd0')], { startLine: 9, endLine: 11 }),
|
||||
block('4', 'e', [], { startLine: 13 }),
|
||||
]
|
||||
|
||||
function tree(removedList: RemovedView[] = []): NonNullable<ReturnType<typeof diffTree>> {
|
||||
return diffTree(TREE_BLOCKS, diff({
|
||||
blocks: { a: { change: 'mod' }, a1: { change: 'mod', own: true }, d: { change: 'add', outermost: true }, d0: { change: 'add' } },
|
||||
removed: removedList,
|
||||
}), 2, () => true)!
|
||||
}
|
||||
|
||||
describe('foldUnchanged', () => {
|
||||
it('每层连着没变的块折成一段,改过的块下面同样按层折', () => {
|
||||
const { runs, folded } = foldUnchanged(TREE_BLOCKS, tree(), () => true, new Set(), new Set())
|
||||
expect([...runs]).toEqual([['0.0', 1], ['0.2', 1], ['1', 2], ['4', 1]])
|
||||
expect([...folded].sort()).toEqual(['0.0', '0.2', '1', '2', '4'])
|
||||
})
|
||||
|
||||
it('删掉的块排在哪块后面,那一段就在哪儿断开', () => {
|
||||
const { runs } = foldUnchanged(TREE_BLOCKS, tree([removed('', 'b')]), () => true, new Set(), new Set())
|
||||
expect([...runs]).toContainEqual(['1', 1])
|
||||
expect([...runs]).toContainEqual(['2', 1])
|
||||
})
|
||||
|
||||
it('被筛掉的块不算也不打断;点开过的段、要露出来的块不折', () => {
|
||||
expect([...foldUnchanged(TREE_BLOCKS, tree(), block => block.id !== '2', new Set(), new Set()).runs]).toContainEqual(['1', 1])
|
||||
expect(foldUnchanged(TREE_BLOCKS, tree(), () => true, new Set(['1']), new Set()).runs.has('1')).toBe(false)
|
||||
expect(foldUnchanged(TREE_BLOCKS, tree(), () => true, new Set(), new Set(['2'])).folded.has('2')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('changeStops', () => {
|
||||
it('新增的最外面那块、自己改了的修改块、删掉的块,照页面上的先后;修改块只算自己那几行', () => {
|
||||
const stops = changeStops(TREE_BLOCKS, tree([removed('', 'c'), removed('a', undefined)]), new Set())
|
||||
expect(stops.map(stop => [stop.id, stop.change, stop.from, stop.to, stop.ancestors])).toEqual([
|
||||
['removed-1', 'del', 3, 3, ['0']],
|
||||
['0.1', 'mod', 2, 2, ['0']],
|
||||
['removed-0', 'del', 3, 3, []],
|
||||
['3', 'add', 9, 11, []],
|
||||
])
|
||||
})
|
||||
|
||||
it('被筛掉的块和它下面的不算', () => {
|
||||
expect(changeStops(TREE_BLOCKS, tree(), new Set(['3', '3.0'])).map(stop => stop.id)).toEqual(['0.1'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('nextStop', () => {
|
||||
const stops = [{ from: 2 }, { from: 9 }, { from: 20 }].map((stop, index) => ({ id: String(index), change: 'mod' as const, to: stop.from, ancestors: [], ...stop }))
|
||||
|
||||
it('接着刚跳到的那处走,到头绕回另一头', () => {
|
||||
expect(nextStop(stops, { index: 0 }, 1)).toBe(1)
|
||||
expect(nextStop(stops, { index: 2 }, 1)).toBe(0)
|
||||
expect(nextStop(stops, { index: 0 }, -1)).toBe(2)
|
||||
})
|
||||
|
||||
it('按视口顶上那块的行找:下一处在它后面,上一处在它前面', () => {
|
||||
expect(nextStop(stops, { line: 9 }, 1)).toBe(2)
|
||||
expect(nextStop(stops, { line: 9 }, -1)).toBe(0)
|
||||
expect(nextStop(stops, { line: 30 }, 1)).toBe(0)
|
||||
expect(nextStop(stops, { line: 0 }, -1)).toBe(2)
|
||||
expect(nextStop(stops, {}, 1)).toBe(0)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user