✨ feat(vscode): 代码阅读预览加 ⌘F 查找栏:整份文件查(折叠着的块里的也算,跳过去时展开),按页面上显示的字不分大小写匹配、中文名也认原名,Enter / ⌘G 跳、Esc 关,高亮直接画在页面上不重画卡片

This commit is contained in:
cruldra committed 2026-10-14 05:40:59 +11:00
1 parent cc3fcda051
commit bd474986bd
27 files changed
+1833 -114

No files matched your search

@@ -44,6 +44,7 @@ import { definitionKind, findDefinitions, languageDefinitions, pickDefinition, r
import { DefinitionSources } from './definitionSources'
import { documentMessage, pageDocument } from './documentMessage'
import { documentSymbolNodes } from './documentSymbols'
import { FIND_CONTEXT } from './findCommands'
import { NavigationContext, OCCURRENCES_CONTEXT } from './occurrenceNavigation'
import { occurrencesOf } from './occurrences'
import { languageOf, openingFor } from './openTarget'
@@ -80,6 +81,8 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
private readonly requests = new Map<string, OpenRequest>()
/** 哪个预览眼下能用键盘在高亮的各处出现之间跳,跟着它设快捷键 when 子句用的上下文键 */
readonly navigation = new NavigationContext<Preview>(value => void commands.executeCommand('setContext', OCCURRENCES_CONTEXT, value))
/** 哪个预览眼下查找栏开着、有焦点,跟着它设查找下一处 / 上一处快捷键 when 子句用的上下文键 */
readonly finding = new NavigationContext<Preview>(value => void commands.executeCommand('setContext', FIND_CONTEXT, value))
/** 调用的名字的定义是哪种块:各预览共用,定义所在的文件同一版只解析一次 */
readonly definitionKinds: DefinitionKinds
@@ -153,6 +156,7 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
panel.onDidDispose(() => {
this.previews.delete(preview)
this.navigation.update(preview, false)
this.finding.update(preview, false)
preview.dispose()
})
}
@@ -162,6 +166,16 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
this.navigation.target(this.previews, preview => preview.active)?.moveOccurrence(step)
}
/** 「查找」:打开查找栏。发给查找栏开着、有焦点的那个预览,没有就发给活动的预览。 */
find(): void {
this.finding.target(this.previews, preview => preview.active)?.find()
}
/** 「查找下一处 / 上一处」:发给查找栏开着、有焦点的那个预览,从命令面板运行时发给活动的预览。 */
moveFind(step: 1 | -1): void {
this.finding.target(this.previews, preview => preview.active)?.moveFind(step)
}
/** 让已打开的预览按当前注册表重发;给了 languageId 就只刷这种语言的。 */
refresh(languageId?: string): void {
for (const preview of this.previews) {
@@ -539,6 +553,18 @@ class Preview {
this.post({ type: 'moveOccurrence', step })
}
/** 打开查找栏;页面还没 ready 就算了。 */
find(): void {
if (this.ready)
this.post({ type: 'openFind' })
}
/** 查找栏里跳到下一处 / 上一处命中;页面还没 ready 就算了(还没有查找栏)。 */
moveFind(step: 1 | -1): void {
if (this.ready)
this.post({ type: 'moveFind', step })
}
/** 开着时又被点开(见 [PreviewEditorProvider.open]):这次说了从哪儿打开的就按它重新比,没说的照旧;要滚到哪、要不要聚焦输入框照这次的。 */
reopen(request: OpenRequest): void {
if (request.from !== undefined) {
@@ -744,6 +770,9 @@ class Preview {
return
case 'occurrenceNavigation':
this.owner.navigation.update(this, msg.available)
return
case 'findNavigation':
this.owner.finding.update(this, msg.available)
}
}