✨ feat(vscode): 跳定义、点链接、编辑切回预览不改开着的预览对比什么

This commit is contained in:
cruldra committed 2026-10-12 16:10:41 +11:00
1 parent d4416e7b26
commit ce5327dcd5
8 files changed
+239 -47

No files matched your search

+30 -12
View File
@@ -54,9 +54,11 @@ const REFRESH_DELAY_MS = 150
/**
* 一次打开预览带的话:这个标签页是从哪儿打开的(定对比什么);要滚到哪(从文本编辑器切过来时它顶部那一行,或跳到的定义);
* 要不要把光标放进顶部「问 AI」输入框(侧栏「问 AI」打开的)。
*
* 只有侧栏各栏点开文件、「编辑」切回「预览」带 `from`;跳定义、点链接、问 AI 这些只是去看一眼,不带:新开的预览不比,已经开着的照旧。
*/
export interface OpenRequest {
from: OpenedFrom
from?: OpenedFrom
reveal?: Reveal
focusPath?: boolean
}
@@ -149,9 +151,19 @@ export class PreviewEditorProvider implements CustomTextEditorProvider {
/** uri 的预览视口顶部那块的起始行;几个编辑器组里都开着这个文件的预览时取活动的那个。 */
visibleLine(uri: Uri): number | undefined {
return this.shown(uri)?.visibleLine
}
/** uri 的预览这个标签页是从哪儿打开的;几个编辑器组里都开着时取活动的那个,页面还没准备好、不知道的没有。 */
openedFrom(uri: Uri): OpenedFrom | undefined {
return this.shown(uri)?.openedFrom
}
/** uri 的预览:几个编辑器组里都开着时取活动的那个。 */
private shown(uri: Uri): Preview | undefined {
const key = uri.toString()
const previews = [...this.previews].filter(p => p.uri.toString() === key)
return (previews.find(p => p.active) ?? previews[0])?.visibleLine
return previews.find(p => p.active) ?? previews[0]
}
}
@@ -201,7 +213,7 @@ class Preview {
* 之后页面因标签页切走重新加载,按 webview 自己记的位置恢复
*/
private pendingReveal: Reveal | undefined
/** 这个标签页是从哪儿打开的,定对比什么;没带打开请求的(VS Code 重启后恢复的)先空着,页面 ready 时按它记着的定 */
/** 这个标签页是从哪儿打开的,定对比什么;打开请求没说的(跳定义新开的、VS Code 重启后恢复的)先空着,页面 ready 时按它记着的定 */
private from: OpenedFrom | undefined
constructor(
@@ -334,6 +346,10 @@ class Preview {
return this.panel.active
}
get openedFrom(): OpenedFrom | undefined {
return this.from
}
async push(): Promise<void> {
clearTimeout(this.timer)
if (!this.ready)
@@ -470,13 +486,15 @@ class Preview {
this.post({ type: 'moveOccurrence', step })
}
/** 开着时又被点开(见 [PreviewEditorProvider.open]):按这次是从哪儿打开的重新比,要滚到哪、要不要聚焦输入框照这次的。 */
/** 开着时又被点开(见 [PreviewEditorProvider.open]):这次说了从哪儿打开的就按它重新比,没说的照旧;要滚到哪、要不要聚焦输入框照这次的。 */
reopen(request: OpenRequest): void {
this.from = request.from
if (this.ready) {
this.post({ type: 'openedFrom', from: request.from })
if (this.sent)
void this.diff.update(this.sent)
if (request.from !== undefined) {
this.from = request.from
if (this.ready) {
this.post({ type: 'openedFrom', from: request.from })
if (this.sent)
void this.diff.update(this.sent)
}
}
if (request.reveal)
this.reveal(request.reveal)
@@ -575,7 +593,7 @@ class Preview {
switch (msg.type) {
case 'ready':
this.ready = true
// 打开请求说了从哪儿打开的就按它;没说的(VS Code 重启后恢复的)按页面记着的,页面也没记过的不算从「未提交的更改」点开的
// 打开请求说了从哪儿打开的就按它;没说的按页面记着的(VS Code 重启后恢复的),页面也没记过的(新开的)不比
this.from ??= msg.openedFrom ?? 'other'
this.post({ type: 'openedFrom', from: this.from })
// 先于文档发:第一份文档按筛选画,不会先整份露出来再藏
@@ -794,7 +812,7 @@ class Preview {
}
/**
* 在预览所在的编辑器组打开别的文件,和普通编辑器里 ⌘ + 点击一样:语言有代码阅读的用预览打开(算从别处打开的,不对比上一次提交),给了 spot 就滚过去、闪这处;
* 在预览所在的编辑器组打开别的文件,和普通编辑器里 ⌘ + 点击一样:语言有代码阅读的用预览打开(新开的不比,已经开着的照旧),给了 spot 就滚过去、闪这处;
* 其余用 VS Code 默认的打开方式,给了 spot 就选中它(见 openingFor)。目标是否按「预览标签」打开听 VS Code 的设置,
* workbench.editor.enablePreviewFromCodeNavigation 为假时先把当前这个预览标签固定住,免得被目标替掉。
*/
@@ -807,7 +825,7 @@ class Preview {
await commands.executeCommand('vscode.open', uri, { ...options, ...(opening.selection && { selection: opening.selection }) })
return
}
await this.owner.open(uri, { from: 'other', ...(opening.reveal && { reveal: opening.reveal }) }, () => commands.executeCommand('vscode.openWith', uri, PREVIEW_VIEW_TYPE, options))
await this.owner.open(uri, opening.reveal ? { reveal: opening.reveal } : {}, () => commands.executeCommand('vscode.openWith', uri, PREVIEW_VIEW_TYPE, options))
}
/** 点了调用树上的一个节点:打开它在的文件,滚到这一处(同 ⌘ + 点击跳到别的文件)。 */