🐛 fix(vscode): 代码阅读预览记住浏览位置,编辑 / 预览互切位置对齐
This commit is contained in:
1 parent
6897954644
commit
37306bd23e
13 files changed
+409
-37
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import type { Disposable, TextEditor } from 'vscode'
|
||||
import type { PreviewEditorProvider } from './previewEditor'
|
||||
import { commands, Range, TabInputCustom, TextEditorRevealType, Uri, window } from 'vscode'
|
||||
import { PREVIEW_VIEW_TYPE } from './previewEditor'
|
||||
|
||||
/** VS Code 自带普通文本编辑器的 editor id。 */
|
||||
const TEXT_EDITOR = 'default'
|
||||
/**
|
||||
* VS Code 自带的「重新打开编辑器的方式」:在原标签页位置换成另一种编辑器,新编辑器打开后才返回。
|
||||
* 原文件有未保存改动也不弹保存框——改动在 TextDocument 里,不跟着标签页走。
|
||||
*/
|
||||
const REOPEN_WITH = 'reopenActiveEditorWith'
|
||||
/** 切换命令返回时文本编辑器还没同步到扩展这边的话,最多再等这么久 */
|
||||
const EDITOR_WAIT_MS = 1000
|
||||
|
||||
function sameUri(a: Uri, b: Uri): boolean {
|
||||
return a.toString() === b.toString()
|
||||
}
|
||||
|
||||
/** 标题栏按钮传来的是 (文件 Uri, { groupId }),命令面板里调用时没有参数。 */
|
||||
function resourceArg(args: unknown[]): Uri | undefined {
|
||||
return args[0] instanceof Uri ? args[0] : undefined
|
||||
}
|
||||
|
||||
function activeCustomEditorUri(): Uri | undefined {
|
||||
const input = window.tabGroups.activeTabGroup.activeTab?.input
|
||||
return input instanceof TabInputCustom ? input.uri : undefined
|
||||
}
|
||||
|
||||
function textEditorOf(uri: Uri): TextEditor | undefined {
|
||||
const active = window.activeTextEditor
|
||||
if (active && sameUri(active.document.uri, uri))
|
||||
return active
|
||||
return window.visibleTextEditors.find(editor => sameUri(editor.document.uri, uri))
|
||||
}
|
||||
|
||||
/** 编辑器变化和命令结果是分开通知到扩展这边的:没看到 uri 的文本编辑器就等它出现。 */
|
||||
function waitForTextEditor(uri: Uri): Promise<TextEditor | undefined> {
|
||||
const found = textEditorOf(uri)
|
||||
if (found)
|
||||
return Promise.resolve(found)
|
||||
const disposables: Disposable[] = []
|
||||
return new Promise<TextEditor | undefined>((resolve) => {
|
||||
disposables.push(window.onDidChangeVisibleTextEditors(() => {
|
||||
const editor = textEditorOf(uri)
|
||||
if (editor)
|
||||
resolve(editor)
|
||||
}))
|
||||
const timer = setTimeout(resolve, EDITOR_WAIT_MS, undefined)
|
||||
disposables.push({ dispose: () => clearTimeout(timer) })
|
||||
}).finally(() => disposables.forEach(d => d.dispose()))
|
||||
}
|
||||
|
||||
/** 文本编辑器 → 预览(同一标签页原位替换):新预览先滚到文本编辑器顶部那一行所在的块。 */
|
||||
export async function showPreview(previews: PreviewEditorProvider, args: unknown[]): Promise<void> {
|
||||
const uri = resourceArg(args) ?? window.activeTextEditor?.document.uri
|
||||
const topLine = uri ? textEditorOf(uri)?.visibleRanges[0]?.start.line : undefined
|
||||
const reopen = (): Thenable<unknown> => commands.executeCommand(REOPEN_WITH, PREVIEW_VIEW_TYPE, ...args)
|
||||
if (uri && topLine !== undefined)
|
||||
await previews.openAtLine(uri, topLine, reopen)
|
||||
else
|
||||
await reopen()
|
||||
}
|
||||
|
||||
/** 预览 → 文本编辑器(同一标签页原位替换):把预览视口顶部那块的起始行放到文本编辑器顶部。 */
|
||||
export async function showSource(previews: PreviewEditorProvider, args: unknown[]): Promise<void> {
|
||||
const uri = resourceArg(args) ?? activeCustomEditorUri()
|
||||
const line = uri ? previews.visibleLine(uri) : undefined
|
||||
await commands.executeCommand(REOPEN_WITH, TEXT_EDITOR, ...args)
|
||||
if (!uri || line === undefined)
|
||||
return
|
||||
const editor = await waitForTextEditor(uri)
|
||||
if (!editor)
|
||||
return
|
||||
const target = Math.min(line, editor.document.lineCount - 1)
|
||||
editor.revealRange(new Range(target, 0, target, 0), TextEditorRevealType.AtTop)
|
||||
}
|
||||
Reference in new issue
Block a user