fix: split terminal inside current panel instead of at root

When clicking split on a terminal, the new terminal is now added
as a sibling of that specific terminal rather than at the root
of the layout tree.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
SuperComboGamer
2025-12-13 01:07:33 -05:00
parent 18494547bc
commit be4a0b292c
2 changed files with 42 additions and 10 deletions

View File

@@ -257,7 +257,8 @@ export function TerminalView() {
};
// Create a new terminal session
const createTerminal = async (direction?: "horizontal" | "vertical") => {
// targetSessionId: the terminal to split (if splitting an existing terminal)
const createTerminal = async (direction?: "horizontal" | "vertical", targetSessionId?: string) => {
try {
const headers: Record<string, string> = {
"Content-Type": "application/json",
@@ -278,7 +279,7 @@ export function TerminalView() {
const data = await response.json();
if (data.success) {
addTerminalToLayout(data.data.id, direction);
addTerminalToLayout(data.data.id, direction, targetSessionId);
} else {
console.error("[Terminal] Failed to create session:", data.error);
}
@@ -358,8 +359,8 @@ export function TerminalView() {
isActive={terminalState.activeSessionId === content.sessionId}
onFocus={() => setActiveTerminalSession(content.sessionId)}
onClose={() => killTerminal(content.sessionId)}
onSplitHorizontal={() => createTerminal("horizontal")}
onSplitVertical={() => createTerminal("vertical")}
onSplitHorizontal={() => createTerminal("horizontal", content.sessionId)}
onSplitVertical={() => createTerminal("vertical", content.sessionId)}
isDragging={activeDragId === content.sessionId}
isDropTarget={activeDragId !== null && activeDragId !== content.sessionId}
fontSize={terminalFontSize}

View File

@@ -593,7 +593,7 @@ export interface AppActions {
// Terminal actions
setTerminalUnlocked: (unlocked: boolean, token?: string) => void;
setActiveTerminalSession: (sessionId: string | null) => void;
addTerminalToLayout: (sessionId: string, direction?: "horizontal" | "vertical") => void;
addTerminalToLayout: (sessionId: string, direction?: "horizontal" | "vertical", targetSessionId?: string) => void;
removeTerminalFromLayout: (sessionId: string) => void;
swapTerminals: (sessionId1: string, sessionId2: string) => void;
clearTerminalState: () => void;
@@ -1534,7 +1534,7 @@ export const useAppStore = create<AppState & AppActions>()(
});
},
addTerminalToLayout: (sessionId, direction = "horizontal") => {
addTerminalToLayout: (sessionId, direction = "horizontal", targetSessionId) => {
const current = get().terminalState;
const newTerminal: TerminalPanelContent = { type: "terminal", sessionId, size: 50 };
@@ -1556,7 +1556,33 @@ export const useAppStore = create<AppState & AppActions>()(
const activeTab = current.tabs.find(t => t.id === current.activeTabId);
if (!activeTab) return;
const addToLayout = (
// If targetSessionId is provided, find and split that specific terminal
const splitTargetTerminal = (
node: TerminalPanelContent,
targetId: string,
targetDirection: "horizontal" | "vertical"
): TerminalPanelContent => {
if (node.type === "terminal") {
if (node.sessionId === targetId) {
// Found the target - split it
return {
type: "split",
direction: targetDirection,
panels: [{ ...node, size: 50 }, newTerminal],
};
}
// Not the target, return unchanged
return node;
}
// It's a split - recurse into panels
return {
...node,
panels: node.panels.map(p => splitTargetTerminal(p, targetId, targetDirection)),
};
};
// Legacy behavior: add to root layout (when no targetSessionId)
const addToRootLayout = (
node: TerminalPanelContent,
targetDirection: "horizontal" | "vertical"
): TerminalPanelContent => {
@@ -1583,9 +1609,14 @@ export const useAppStore = create<AppState & AppActions>()(
};
};
const newLayout = activeTab.layout
? addToLayout(activeTab.layout, direction)
: { type: "terminal" as const, sessionId, size: 100 };
let newLayout: TerminalPanelContent;
if (!activeTab.layout) {
newLayout = { type: "terminal", sessionId, size: 100 };
} else if (targetSessionId) {
newLayout = splitTargetTerminal(activeTab.layout, targetSessionId, direction);
} else {
newLayout = addToRootLayout(activeTab.layout, direction);
}
const newTabs = current.tabs.map(t =>
t.id === current.activeTabId ? { ...t, layout: newLayout } : t