✨ feat(vscode): 跳定义、点链接、编辑切回预览不改开着的预览对比什么
This commit is contained in:
1 parent
d4416e7b26
commit
ce5327dcd5
8 files changed
+239
-47
No files matched your search
@@ -136,7 +136,7 @@ export interface StickyScrollSettings {
|
||||
* displayNames:version 这份文档里显示成中文名的名字,查到一步发一步(先本文件定义的,再别的文件定义的);不是页面上这个版本的不理
|
||||
* diff:这份文件相比对比基准改了什么(审查工作副本里的、从「未提交的更改」点开的有改动的才有,见 [对比基准](vscode/src/codeReader/diff/diffBase.ts#DiffBase)):每发一份文档之后算好了补发,
|
||||
* 基准变了(提交后 HEAD 动了、换了审查的工单、文件有了改动、这个标签页换了从哪儿打开)再发;null 是不比了(退出了审查、改动提交了、从别处点开了)
|
||||
* openedFrom:这个标签页是从哪儿打开的,页面记进自己的状态,VS Code 重启后恢复这个标签页时随 ready 报回来;ready 后发一次,开着时又被点开再发
|
||||
* openedFrom:这个标签页是从哪儿打开的,页面记进自己的状态,VS Code 重启后恢复这个标签页时随 ready 报回来;ready 后发一次,开着时又从侧栏点开、换了从哪儿打开的再发
|
||||
* repoLinksChecked:id 那次 checkRepoLinks 的回答,missing 是仓库里没有的路径,unresolved 是找不到的不带路径的引用
|
||||
* repoLinkBroken:这个仓库链接打不开。没有 symbol 是文件或目录没有;有 symbol 是文件在、这个符号没有;没有 path 是不带路径的引用找不到
|
||||
* repoLinkOpened:这个仓库链接打开了。路径在;带了 symbol 时这个符号也在;没有 path 是不带路径的引用找到了
|
||||
|
||||
@@ -218,7 +218,28 @@ describe('预览对比什么看这个标签页是从哪儿打开的', () => {
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(comparedWithHead))
|
||||
})
|
||||
|
||||
it('开着的预览再从别处点开就不比,再从「未提交的更改」点开又比;只切标签页不变', async () => {
|
||||
it('跳定义、点链接打到开着的预览不改它对比什么、只滚过去;要新开的预览不比', async () => {
|
||||
const { provider, document, diffBase } = opening()
|
||||
const page = tab()
|
||||
await provider.open(document.uri as never, { from: 'uncommitted' }, async () => provider.resolveCustomTextEditor(document as never, page.panel))
|
||||
await page.send({ type: 'ready' })
|
||||
await vi.waitFor(() => expect(page.posted()).toContainEqual(comparedWithHead))
|
||||
|
||||
page.clear()
|
||||
await provider.open(document.uri as never, { reveal: { line: 1 } }, async () => {})
|
||||
expect(page.posted()).toEqual([{ type: 'reveal', line: 1 }])
|
||||
expect(provider.openedFrom(document.uri as never)).toBe('uncommitted')
|
||||
|
||||
diffBase.mockClear()
|
||||
const fresh = tab()
|
||||
await provider.open(document.uri as never, { reveal: { line: 1 } }, async () => provider.resolveCustomTextEditor(document as never, fresh.panel))
|
||||
await fresh.send({ type: 'ready' })
|
||||
expect(fresh.posted()).toContainEqual({ type: 'openedFrom', from: 'other' })
|
||||
expect(diffBase).toHaveBeenCalledWith(document.uri, 'other')
|
||||
expect(diffBase).not.toHaveBeenCalledWith(document.uri, 'uncommitted')
|
||||
})
|
||||
|
||||
it('开着的预览再从主栏点开就不比,再从「未提交的更改」点开又比;只切标签页不变', async () => {
|
||||
const { provider, document } = opening()
|
||||
const page = tab()
|
||||
await provider.open(document.uri as never, { from: 'uncommitted' }, async () => provider.resolveCustomTextEditor(document as never, page.panel))
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
/** 点了调用树上的一个节点:打开它在的文件,滚到这一处(同 ⌘ + 点击跳到别的文件)。 */
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { OpenedFrom } from '../diff/diffBase'
|
||||
import type { OpenRequest } from './previewEditor'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { EditorSwitch } from './switchEditor'
|
||||
|
||||
/** 假的 VS Code:文件、标签页的输入、活动的文本编辑器、标签页关掉的通知 */
|
||||
const fake = vi.hoisted(() => {
|
||||
class Uri {
|
||||
constructor(readonly path: string) {}
|
||||
toString(): string {
|
||||
return `file://${this.path}`
|
||||
}
|
||||
}
|
||||
class TabInputText {
|
||||
constructor(readonly uri: Uri) {}
|
||||
}
|
||||
class TabInputCustom {
|
||||
constructor(readonly uri: Uri, readonly viewType: string) {}
|
||||
}
|
||||
const tabListeners = new Set<(event: { closed: unknown[] }) => void>()
|
||||
const window = {
|
||||
activeTextEditor: undefined as unknown,
|
||||
visibleTextEditors: [] as unknown[],
|
||||
onDidChangeVisibleTextEditors: () => ({ dispose: () => {} }),
|
||||
tabGroups: {
|
||||
activeTabGroup: { activeTab: undefined },
|
||||
onDidChangeTabs: (listener: (event: { closed: unknown[] }) => void) => {
|
||||
tabListeners.add(listener)
|
||||
return { dispose: () => tabListeners.delete(listener) }
|
||||
},
|
||||
},
|
||||
}
|
||||
return { Uri, TabInputText, TabInputCustom, window, tabListeners, executeCommand: vi.fn() }
|
||||
})
|
||||
|
||||
vi.mock('vscode', () => ({
|
||||
Uri: fake.Uri,
|
||||
TabInputText: fake.TabInputText,
|
||||
TabInputCustom: fake.TabInputCustom,
|
||||
window: fake.window,
|
||||
commands: { executeCommand: fake.executeCommand },
|
||||
Range: class {
|
||||
constructor(readonly startLine: number, readonly startCharacter: number, readonly endLine: number, readonly endCharacter: number) {}
|
||||
},
|
||||
TextEditorRevealType: { AtTop: 3 },
|
||||
}))
|
||||
vi.mock('./previewEditor', () => ({ PREVIEW_VIEW_TYPE: 'superpowers.codeReader.preview' }))
|
||||
|
||||
const uri = new fake.Uri('/workspace/web/a.ts')
|
||||
/** 第 1 个编辑器组里 a.ts 的文本编辑器,顶部是第 10 行 */
|
||||
const editor = { document: { uri, lineCount: 100 }, viewColumn: 1, visibleRanges: [{ start: { line: 10 } }], revealRange: vi.fn() }
|
||||
|
||||
/** 开着的预览:从 from 打开的;open 照 VS Code 那样执行打开 */
|
||||
function previews(from: OpenedFrom | undefined) {
|
||||
return {
|
||||
visibleLine: () => 10,
|
||||
openedFrom: () => from,
|
||||
open: vi.fn(async (_uri: unknown, _request: OpenRequest, show: () => Thenable<unknown>) => {
|
||||
await show()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
fake.window.activeTextEditor = undefined
|
||||
fake.window.visibleTextEditors = []
|
||||
fake.tabListeners.clear()
|
||||
// 换成文本编辑器后,a.ts 的文本编辑器就是活动的那个
|
||||
fake.executeCommand.mockImplementation(async (command: string, editorId: string) => {
|
||||
if (command === 'reopenActiveEditorWith' && editorId === 'default') {
|
||||
fake.window.activeTextEditor = editor
|
||||
fake.window.visibleTextEditors = [editor]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('编辑器右上角「预览 / 编辑」切换', () => {
|
||||
it('预览切到文本编辑器再切回来:照切走前的从哪儿打开,滚到文本编辑器顶部那一行', async () => {
|
||||
const opened = previews('uncommitted')
|
||||
const switcher = new EditorSwitch(opened as never)
|
||||
await switcher.showSource([uri, { groupId: 1 }])
|
||||
await switcher.showPreview([uri, { groupId: 1 }])
|
||||
|
||||
expect(opened.open).toHaveBeenLastCalledWith(uri, { from: 'uncommitted', reveal: { line: 10 } }, expect.any(Function))
|
||||
switcher.dispose()
|
||||
})
|
||||
|
||||
it('文本编辑器不是从预览切过来的:切到预览不带从哪儿打开(新开的预览不比)', async () => {
|
||||
const opened = previews('uncommitted')
|
||||
const switcher = new EditorSwitch(opened as never)
|
||||
fake.window.activeTextEditor = editor
|
||||
fake.window.visibleTextEditors = [editor]
|
||||
await switcher.showPreview([uri, { groupId: 1 }])
|
||||
|
||||
expect(opened.open).toHaveBeenLastCalledWith(uri, { reveal: { line: 10 } }, expect.any(Function))
|
||||
switcher.dispose()
|
||||
})
|
||||
|
||||
it('切过去的那个文本编辑器标签页关了就忘掉;别的编辑器组里关的不算', async () => {
|
||||
const opened = previews('uncommitted')
|
||||
const switcher = new EditorSwitch(opened as never)
|
||||
await switcher.showSource([uri, { groupId: 1 }])
|
||||
fake.tabListeners.forEach(listener => listener({ closed: [{ input: new fake.TabInputText(uri), group: { viewColumn: 2 } }] }))
|
||||
await switcher.showPreview([uri, { groupId: 1 }])
|
||||
expect(opened.open).toHaveBeenLastCalledWith(uri, { from: 'uncommitted', reveal: { line: 10 } }, expect.any(Function))
|
||||
|
||||
fake.tabListeners.forEach(listener => listener({ closed: [{ input: new fake.TabInputText(uri), group: { viewColumn: 1 } }] }))
|
||||
await switcher.showPreview([uri, { groupId: 1 }])
|
||||
expect(opened.open).toHaveBeenLastCalledWith(uri, { reveal: { line: 10 } }, expect.any(Function))
|
||||
switcher.dispose()
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Disposable, TextEditor } from 'vscode'
|
||||
import type { Disposable, TextEditor, ViewColumn } from 'vscode'
|
||||
import type { OpenedFrom } from '../diff/diffBase'
|
||||
import type { PreviewEditorProvider } from './previewEditor'
|
||||
import { commands, Range, TabInputCustom, TextEditorRevealType, Uri, window } from 'vscode'
|
||||
import { commands, Range, TabInputCustom, TabInputText, TextEditorRevealType, Uri, window } from 'vscode'
|
||||
import { PREVIEW_VIEW_TYPE } from './previewEditor'
|
||||
|
||||
/** VS Code 自带普通文本编辑器的 editor id。 */
|
||||
@@ -51,27 +52,63 @@ function waitForTextEditor(uri: Uri): Promise<TextEditor | undefined> {
|
||||
}).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)
|
||||
await previews.open(uri, { from: 'other', ...(topLine !== undefined && { reveal: { line: topLine } }) }, reopen)
|
||||
else
|
||||
await reopen()
|
||||
/** 一个编辑器组里的一个文件:同一个标签页在预览和文本编辑器之间换着看时按它认。 */
|
||||
function tabKey(viewColumn: ViewColumn | undefined, uri: Uri): string {
|
||||
return `${viewColumn ?? ''}:${uri.toString()}`
|
||||
}
|
||||
|
||||
/** 预览 → 文本编辑器(同一标签页原位替换):把预览视口顶部那块的起始行放到文本编辑器顶部。 */
|
||||
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)
|
||||
/**
|
||||
* 编辑器右上角的「预览 / 编辑」:同一个标签页原位换成另一种编辑器,换回预览时照切走前的样子对比,不算从别处重新打开。
|
||||
* 切走的预览是从哪儿打开的按编辑器组和文件记着,换上的那个文本编辑器标签页关了就忘掉。
|
||||
*/
|
||||
export class EditorSwitch implements Disposable {
|
||||
/** 切到文本编辑器的预览原来是从哪儿打开的,按 [tabKey] 记 */
|
||||
private readonly sourceFrom = new Map<string, OpenedFrom>()
|
||||
private readonly closing: Disposable
|
||||
|
||||
constructor(private readonly previews: Pick<PreviewEditorProvider, 'open' | 'visibleLine' | 'openedFrom'>) {
|
||||
this.closing = window.tabGroups.onDidChangeTabs(({ closed }) => {
|
||||
for (const tab of closed) {
|
||||
if (tab.input instanceof TabInputText)
|
||||
this.sourceFrom.delete(tabKey(tab.group.viewColumn, tab.input.uri))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 文本编辑器 → 预览:新预览先滚到文本编辑器顶部那一行所在的块;这个文本编辑器是从预览切过来的,照原来的从哪儿打开。 */
|
||||
async showPreview(args: unknown[]): Promise<void> {
|
||||
const uri = resourceArg(args) ?? window.activeTextEditor?.document.uri
|
||||
const reopen = (): Thenable<unknown> => commands.executeCommand(REOPEN_WITH, PREVIEW_VIEW_TYPE, ...args)
|
||||
if (!uri) {
|
||||
await reopen()
|
||||
return
|
||||
}
|
||||
const editor = textEditorOf(uri)
|
||||
const topLine = editor?.visibleRanges[0]?.start.line
|
||||
const from = editor && this.sourceFrom.get(tabKey(editor.viewColumn, uri))
|
||||
await this.previews.open(uri, { ...(from && { from }), ...(topLine !== undefined && { reveal: { line: topLine } }) }, reopen)
|
||||
}
|
||||
|
||||
/** 预览 → 文本编辑器:把预览视口顶部那块的起始行放到文本编辑器顶部,记下这个预览是从哪儿打开的。 */
|
||||
async showSource(args: unknown[]): Promise<void> {
|
||||
const uri = resourceArg(args) ?? activeCustomEditorUri()
|
||||
const line = uri ? this.previews.visibleLine(uri) : undefined
|
||||
const from = uri ? this.previews.openedFrom(uri) : undefined
|
||||
await commands.executeCommand(REOPEN_WITH, TEXT_EDITOR, ...args)
|
||||
if (!uri || (line === undefined && from === undefined))
|
||||
return
|
||||
const editor = await waitForTextEditor(uri)
|
||||
if (!editor)
|
||||
return
|
||||
if (from)
|
||||
this.sourceFrom.set(tabKey(editor.viewColumn, uri), from)
|
||||
if (line === undefined)
|
||||
return
|
||||
const target = Math.min(line, editor.document.lineCount - 1)
|
||||
editor.revealRange(new Range(target, 0, target, 0), TextEditorRevealType.AtTop)
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.closing.dispose()
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import { NEXT_OCCURRENCE, PREVIOUS_OCCURRENCE } from './editor/occurrenceNavigat
|
||||
import { languageOf, openingFor } from './editor/openTarget'
|
||||
import { PATH_PREVIEW_SCHEME } from './editor/pathPreview'
|
||||
import { PREVIEW_VIEW_TYPE, PreviewEditorProvider } from './editor/previewEditor'
|
||||
import { showPreview, showSource } from './editor/switchEditor'
|
||||
import { EditorSwitch } from './editor/switchEditor'
|
||||
import { WorkspaceEntries } from './entries/workspaceEntries'
|
||||
import { registerCopyCommands } from './explorer/copyCommands'
|
||||
import { FileTreeProvider } from './explorer/fileTree'
|
||||
@@ -135,9 +135,10 @@ export function registerCodeReader(context: ExtensionContext): CodeReaderApi {
|
||||
uri => locator.reveal(uri),
|
||||
(subject, request) => features.ask(subject, request),
|
||||
)
|
||||
const switcher = new EditorSwitch(previews)
|
||||
const openChat = async (page: Uri | undefined): Promise<void> => {
|
||||
if (page)
|
||||
await previews.open(page, { from: 'other', focusPath: true })
|
||||
await previews.open(page, { focusPath: true })
|
||||
}
|
||||
|
||||
context.subscriptions.push(
|
||||
@@ -153,7 +154,7 @@ export function registerCodeReader(context: ExtensionContext): CodeReaderApi {
|
||||
const languageId = await languageOf(uri)
|
||||
return languageId !== undefined && registry.languageFor(languageId) !== undefined
|
||||
},
|
||||
uri => previews.open(uri, { from: 'other', focusPath: true }),
|
||||
uri => previews.open(uri, { focusPath: true }),
|
||||
),
|
||||
workspace.registerTextDocumentContentProvider(PATH_PREVIEW_SCHEME, {
|
||||
provideTextDocumentContent: () => '',
|
||||
@@ -171,6 +172,7 @@ export function registerCodeReader(context: ExtensionContext): CodeReaderApi {
|
||||
favorites,
|
||||
features,
|
||||
heads,
|
||||
switcher,
|
||||
// 主栏审查时刷新是重读 PR 改过的文件,平时是重读工作区文件树
|
||||
commands.registerCommand('superpowers.codeReader.refresh', () => review.reviewing ? review.reload() : files.refresh()),
|
||||
commands.registerCommand('superpowers.codeReader.pickReviewIssue', () => review.pick()),
|
||||
@@ -201,8 +203,8 @@ export function registerCodeReader(context: ExtensionContext): CodeReaderApi {
|
||||
await openFile(found.uri, 'other', registry, previews, found.spot)
|
||||
}),
|
||||
// 标题栏按钮传来的是 (文件 Uri, { groupId }),原样转给 VS Code 定位是哪一组的哪个标签
|
||||
commands.registerCommand('superpowers.codeReader.showPreview', (...args: unknown[]) => showPreview(previews, args)),
|
||||
commands.registerCommand('superpowers.codeReader.showSource', (...args: unknown[]) => showSource(previews, args)),
|
||||
commands.registerCommand('superpowers.codeReader.showPreview', (...args: unknown[]) => switcher.showPreview(args)),
|
||||
commands.registerCommand('superpowers.codeReader.showSource', (...args: unknown[]) => switcher.showSource(args)),
|
||||
commands.registerCommand(NEXT_OCCURRENCE, () => previews.moveOccurrence(1)),
|
||||
commands.registerCommand(PREVIOUS_OCCURRENCE, () => previews.moveOccurrence(-1)),
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user