feat: add tabbed grids, click-to-expand, and keybind cleanup

Introduces per-tab pane management with independent focus/expansion state,
a persistent tab bar visible in both picker and grid modes, and a 70/30
soft-expand layout triggered by clicking pane bodies. Removes legacy
toggle keybinds (Ctrl+^ and Ctrl+`) leaving only Ctrl+Space.

New keybinds: Ctrl+T new tab, Alt+1-9 switch tab, Alt+n/p cycle tabs,
Ctrl+E toggle click-expand, Ctrl+W auto-removes empty tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-02-28 10:45:25 +00:00
parent cad6df1a9b
commit 9e424c192a
8 changed files with 692 additions and 109 deletions

View File

@@ -1,6 +1,6 @@
import { app } from "../lib/state"
import { updateAll, rebuildDisplayRows } from "../ui/panels"
import { ensureGridView } from "../grid/view-switch"
import { ensureGridView, createNewGridTab, switchToGridTab } from "../grid/view-switch"
import { loadSessions } from "../data/sessions"
import { createSession } from "../pty/session-manager"
@@ -43,11 +43,19 @@ export async function doLaunch() {
if (items.length === 0) return
// Determine target tab: use active grid tab or create a new one
let targetTabId: number
if (app.viewMode === "grid" && app.directGrid && app.gridTabs.length > 0) {
targetTabId = app.directGrid.activeTabId
} else {
targetTabId = createNewGridTab()
}
ensureGridView()
const termW = process.stdout.columns || 120
const termH = process.stdout.rows || 40
const totalPanes = items.length + (app.directGrid?.paneCount || 0)
const totalPanes = items.length + (app.directGrid?.getTabPaneCount(targetTabId) || 0)
const cols = totalPanes <= 1 ? 1 : totalPanes <= 2 ? 2 : totalPanes <= 4 ? 2 : 3
const rows = Math.ceil(totalPanes / cols)
const paneW = Math.max(Math.floor(termW / cols) - 2, 20)
@@ -62,7 +70,7 @@ export async function doLaunch() {
width: paneW,
height: paneH,
})
await app.directGrid!.addPane(session)
await app.directGrid!.addPane(session, targetTabId)
}
app.selectedProjects.clear()