feat(ui): redesign the default shortcut layout around a mod+k leader

Single chords stay for everyday actions; open/go actions move to two-step
mod+k sequences; held mod+digit switches header session tabs and held
mod+alt+digit switches context panel surfaces. Rare actions leave the
shortcut schema for the command palette, every remaining action ships with
a default binding, and stored overrides from the old layout reset once.
Key matching now follows the physical key on non-Latin layouts and for
Option-modified digits on macOS, including in the recording dialog.
This commit is contained in:
Bohdan Triapitsyn
2026-08-26 14:52:31 +03:00
parent 76f977e580
commit 7977842e1e
44 changed files with 389 additions and 322 deletions
+17
View File
@@ -9,6 +9,23 @@ import { useSessionUIStore } from '@/sync/session-ui-store';
* count as neighbours — the same rule the strip uses for rendering. The
* session itself is never touched.
*/
/**
* Activate the nth (0-based) header session tab, counting only tabs whose
* session is present in the loaded session list — the same rule the strip
* uses for rendering, so the digit matches what the user sees.
*/
export const activateSessionTabByIndex = (index: number): boolean => {
const { tabIds } = useSessionTabsStore.getState();
const sessionsById = new Map(
useGlobalSessionsStore.getState().activeSessions.map((session) => [session.id, session] as const),
);
const renderable = tabIds.filter((id) => sessionsById.has(id));
const session = renderable[index] ? sessionsById.get(renderable[index]) : null;
if (!session) return false;
useSessionUIStore.getState().setCurrentSession(session.id, resolveGlobalSessionDirectory(session));
return true;
};
export const closeSessionTabAndActivateNeighbour = (sessionId: string): void => {
const { tabIds, closeTab } = useSessionTabsStore.getState();
if (!tabIds.includes(sessionId)) return;