diff --git a/vscode/src/panel/handlers/terminals.test.ts b/vscode/src/panel/handlers/terminals.test.ts index d1522cf..39469c1 100644 --- a/vscode/src/panel/handlers/terminals.test.ts +++ b/vscode/src/panel/handlers/terminals.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { terminalEditorColumn } from '../terminalColumn' +import { existingTerminalGroupColumn, terminalEditorColumn } from '../terminalColumn' describe('terminalEditorColumn', () => { it('分屏 → 右侧第 2 栏', () => { @@ -9,3 +9,31 @@ describe('terminalEditorColumn', () => { expect(terminalEditorColumn(false)).toBe(-1) }) }) + +describe('existingTerminalGroupColumn', () => { + it('没有任何终端 tab → -1', () => { + expect(existingTerminalGroupColumn([ + { viewColumn: 1, isActive: true, tabs: [{ isTerminal: false }] }, + ])).toBe(-1) + }) + + it('已有一组含终端 → 该组 viewColumn', () => { + expect(existingTerminalGroupColumn([ + { viewColumn: 1, isActive: true, tabs: [{ isTerminal: true }] }, + ])).toBe(1) + }) + + it('多组时活动组有终端 → 活动组', () => { + expect(existingTerminalGroupColumn([ + { viewColumn: 1, isActive: false, tabs: [{ isTerminal: true }] }, + { viewColumn: 2, isActive: true, tabs: [{ isTerminal: true }] }, + ])).toBe(2) + }) + + it('多组时活动组没有终端、另一组有 → 有终端的那组', () => { + expect(existingTerminalGroupColumn([ + { viewColumn: 1, isActive: false, tabs: [{ isTerminal: true }] }, + { viewColumn: 2, isActive: true, tabs: [{ isTerminal: false }] }, + ])).toBe(1) + }) +}) diff --git a/vscode/src/panel/handlers/terminals.ts b/vscode/src/panel/handlers/terminals.ts index 67bb6be..9e9b23a 100644 --- a/vscode/src/panel/handlers/terminals.ts +++ b/vscode/src/panel/handlers/terminals.ts @@ -4,13 +4,25 @@ import type { } from 'vscode' import type { Issue } from '../../gitea/types' import type { KanbanWebviewPanel } from '../KanbanPanel' -import { window } from 'vscode' +import { TabInputTerminal, window } from 'vscode' import { logger } from '../../logging/logger' import { getSettings } from '../../settings/store' -import { terminalEditorColumn } from '../terminalColumn' +import { existingTerminalGroupColumn, terminalEditorColumn } from '../terminalColumn' export function resolveTerminalLocation(panel: KanbanWebviewPanel | null, preserveFocus: boolean): TerminalEditorLocationOptions { - const split = panel ? getSettings(panel.context).splitNewTerminals : true + if (!panel) { + return { + viewColumn: existingTerminalGroupColumn( + window.tabGroups.all.map(g => ({ + viewColumn: g.viewColumn, + isActive: g.isActive, + tabs: g.tabs.map(t => ({ isTerminal: t.input instanceof TabInputTerminal })), + })), + ), + preserveFocus, + } + } + const split = getSettings(panel.context).splitNewTerminals return { viewColumn: terminalEditorColumn(split), preserveFocus } } diff --git a/vscode/src/panel/terminalColumn.ts b/vscode/src/panel/terminalColumn.ts index 45ac4b5..aac099a 100644 --- a/vscode/src/panel/terminalColumn.ts +++ b/vscode/src/panel/terminalColumn.ts @@ -5,3 +5,21 @@ export function terminalEditorColumn(split: boolean): 2 | -1 { return split ? 2 : -1 } + +export interface EditorTabGroupLike { + readonly viewColumn: number + readonly isActive: boolean + readonly tabs: ReadonlyArray<{ readonly isTerminal: boolean }> +} + +/** URI / 无看板开终端:复用已有终端所在组,避免无 panel 时强制劈出第 2 栏。 */ +export function existingTerminalGroupColumn(groups: readonly EditorTabGroupLike[]): number { + const hasTerminal = (g: EditorTabGroupLike) => g.tabs.some(t => t.isTerminal) + const active = groups.find(g => g.isActive && hasTerminal(g)) + if (active) + return active.viewColumn // ① 活动组已有终端 → 加进当前组,不劈栏 + const first = groups.find(hasTerminal) + if (first) + return first.viewColumn // ② 终端在别的组 → 跟过去,不新开一栏 + return -1 // ③ 一个终端组都没有 → Active(当前组只加标签),绝不默认 2 +}