♻️ refactor(vscode): 代码阅读不再在页面里拦 ⌘↓ / ⌘↑,快捷键只在「键盘快捷方式」里绑;跳到下一处时把浏览器自己的滚动拉回来,页面不再先滚到底

This commit is contained in:
cruldra committed 2026-09-27 00:33:18 +08:00
1 parent 0cad5722bb
commit 1b1299dc1f
10 files changed
+157 -165

No files matched your search

@@ -1,12 +1,12 @@
import type { Click, Highlight } from './occurrences'
import type { BlockView, Inline, KeyCombo, Occurrence, PreviewText, PropertyItem, Segment, WebviewToExtension } from './types'
import type { BlockView, Inline, Occurrence, PreviewText, PropertyItem, Segment, WebviewToExtension } from './types'
import { describe, expect, it } from 'vitest'
import { toBlockViews } from '../../../src/codeReader/blockView'
import { createPythonAdapter } from '../../../src/codeReader/languages/python'
import { WASM_DIR, withBlocks } from '../../../src/codeReader/testSupport'
import { pythonZhTranslator } from '../../../src/codeReader/translators/pythonZh'
import { DefinitionLinks } from './definitionLinks'
import { clickAction, isCurrent, matchesKey, occurrenceCount, OccurrenceHighlight, OccurrenceNavigation, occurrenceStyle, segmentOccurrence, stepIndex } from './occurrences'
import { clickAction, isCurrent, KEY_SCROLL_MS, KEY_TO_COMMAND_MS, KeyScroll, occurrenceCount, OccurrenceHighlight, OccurrenceNavigation, occurrenceStyle, segmentOccurrence, stepIndex } from './occurrences'
function name(text: string, offset: number): Segment {
return { text, role: 'variable', offset }
@@ -310,20 +310,43 @@ describe('occurrences:用键盘在各处出现之间跳', () => {
expect(reports()).toEqual([false, true, false, true, false])
})
it('命令绑的键:能跳时拦下浏览器的默认动作(⌘↓ 滚到底),不能跳、别的键、修饰键对不上都不拦', () => {
const keys: KeyCombo[] = [{ key: 'ArrowDown', ctrl: false, shift: false, alt: false, meta: true }, { key: 'j', ctrl: true, shift: false, alt: false, meta: false }]
const press = (key: string, modifiers: Partial<Record<'ctrlKey' | 'shiftKey' | 'altKey' | 'metaKey', boolean>> = {}): Pick<KeyboardEvent, 'key' | 'ctrlKey' | 'shiftKey' | 'altKey' | 'metaKey'> =>
({ key, ctrlKey: false, shiftKey: false, altKey: false, metaKey: false, ...modifiers })
const navigation = new OccurrenceNavigation(() => {}, { focused: true, typing: false })
expect(navigation.blocks(press('ArrowDown', { metaKey: true }), keys)).toBe(false)
navigation.update({ highlighted: true })
expect(navigation.blocks(press('ArrowDown', { metaKey: true }), keys)).toBe(true)
expect(navigation.blocks(press('J', { ctrlKey: true }), keys)).toBe(true)
expect(navigation.blocks(press('ArrowDown', { metaKey: true, shiftKey: true }), keys)).toBe(false)
expect(navigation.blocks(press('ArrowDown'), keys)).toBe(false)
expect(navigation.blocks(press('ArrowUp', { metaKey: true }), keys)).toBe(false)
navigation.update({ typing: true })
expect(navigation.blocks(press('ArrowDown', { metaKey: true }), keys)).toBe(false)
expect(matchesKey(press('ArrowDown', { metaKey: true }), keys[0])).toBe(true)
it('不拦任何键:跳转发来时回到刚按键那一刻的位置(只回一次),隔太久、点过鼠标、没按过键(命令面板)不回', () => {
const scroll = new KeyScroll()
expect(scroll.take(100)).toBeUndefined()
scroll.press({ x: 0, y: 40 }, 1000)
expect(scroll.take(1012)).toEqual({ x: 0, y: 40 })
expect(scroll.take(1013)).toBeUndefined()
scroll.press({ x: 0, y: 40 }, 2000)
expect(scroll.take(2000 + KEY_TO_COMMAND_MS + 1)).toBeUndefined()
scroll.press({ x: 0, y: 40 }, 3000)
scroll.forget()
expect(scroll.take(3010)).toBeUndefined()
})
it('跳完守住跳到的位置:浏览器对那个键自己的滚动晚于命令才开始,按键后 KEY_SCROLL_MS 内滚走了就拉回来', () => {
const scroll = new KeyScroll()
scroll.press({ x: 0, y: 40 }, 1000)
scroll.take(1012)
// 刚回到按键那一刻、还没跳完:守住按键那一刻的位置
expect(scroll.scrolled({ x: 0, y: 300 }, 1020)).toEqual({ x: 0, y: 40 })
scroll.hold({ x: 0, y: 900 })
expect(scroll.scrolled({ x: 0, y: 900 }, 1030)).toBeUndefined()
expect(scroll.scrolled({ x: 0, y: 1200 }, 1040)).toEqual({ x: 0, y: 900 })
expect(scroll.scrolled({ x: 0, y: 1200 }, 1000 + KEY_SCROLL_MS + 1)).toBeUndefined()
expect(scroll.scrolled({ x: 0, y: 1300 }, 1000 + KEY_SCROLL_MS + 2)).toBeUndefined()
})
it('不是按键触发的跳转、又按了键、点了鼠标:不守', () => {
const scroll = new KeyScroll()
scroll.take(10)
scroll.hold({ x: 0, y: 900 })
expect(scroll.scrolled({ x: 0, y: 0 }, 20)).toBeUndefined()
scroll.press({ x: 0, y: 40 }, 1000)
scroll.take(1010)
scroll.press({ x: 0, y: 40 }, 1100)
expect(scroll.scrolled({ x: 0, y: 300 }, 1110)).toBeUndefined()
scroll.take(1120)
scroll.forget()
expect(scroll.scrolled({ x: 0, y: 300 }, 1130)).toBeUndefined()
})
})