feat(cli): keybinding system — Ctrl+L sidebar, Ctrl+N new, Ctrl+K search (TUI-009)
This commit is contained in:
@@ -57,9 +57,26 @@ export function TuiApp({ gatewayUrl, conversationId, sessionCookie }: TuiAppProp
|
|||||||
if (key.ctrl && ch === 'c') {
|
if (key.ctrl && ch === 'c') {
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
// Ctrl+B: toggle sidebar
|
// Ctrl+L: toggle sidebar (refresh on open)
|
||||||
if (key.ctrl && ch === 'b') {
|
if (key.ctrl && ch === 'l') {
|
||||||
|
const willOpen = !appMode.sidebarOpen;
|
||||||
appMode.toggleSidebar();
|
appMode.toggleSidebar();
|
||||||
|
if (willOpen) {
|
||||||
|
void conversations.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ctrl+N: create new conversation and switch to it
|
||||||
|
if (key.ctrl && ch === 'n') {
|
||||||
|
void conversations.createConversation().then((conv) => {
|
||||||
|
if (conv) {
|
||||||
|
socket.switchConversation(conv.id);
|
||||||
|
appMode.setMode('chat');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Ctrl+K: toggle search mode
|
||||||
|
if (key.ctrl && ch === 'k') {
|
||||||
|
appMode.setMode(appMode.mode === 'search' ? 'chat' : 'search');
|
||||||
}
|
}
|
||||||
// Page Up / Page Down: scroll message history (only in chat mode)
|
// Page Up / Page Down: scroll message history (only in chat mode)
|
||||||
if (appMode.mode === 'chat') {
|
if (appMode.mode === 'chat') {
|
||||||
@@ -82,14 +99,22 @@ export function TuiApp({ gatewayUrl, conversationId, sessionCookie }: TuiAppProp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Escape: return to chat from sidebar
|
// Escape: return to chat from sidebar/search; in chat, scroll to bottom
|
||||||
if (key.escape && appMode.mode === 'sidebar') {
|
if (key.escape) {
|
||||||
appMode.setMode('chat');
|
if (appMode.mode === 'sidebar' || appMode.mode === 'search') {
|
||||||
|
appMode.setMode('chat');
|
||||||
|
} else if (appMode.mode === 'chat') {
|
||||||
|
viewport.scrollToBottom();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const inputPlaceholder =
|
const inputPlaceholder =
|
||||||
appMode.mode !== 'chat' ? 'focus is on sidebar… press Esc to return' : undefined;
|
appMode.mode === 'sidebar'
|
||||||
|
? 'focus is on sidebar… press Esc to return'
|
||||||
|
: appMode.mode === 'search'
|
||||||
|
? 'search mode… press Esc to return'
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const messageArea = (
|
const messageArea = (
|
||||||
<Box flexDirection="column" flexGrow={1}>
|
<Box flexDirection="column" flexGrow={1}>
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ export function BottomBar({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box flexDirection="column" paddingX={0} marginTop={0}>
|
<Box flexDirection="column" paddingX={0} marginTop={0}>
|
||||||
|
{/* Line 0: keybinding hints */}
|
||||||
|
<Box>
|
||||||
|
<Text dimColor>^L sidebar · ^N new · ^K search · ^T thinking · PgUp/Dn scroll</Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
{/* Line 1: blank ····· Gateway: Status */}
|
{/* Line 1: blank ····· Gateway: Status */}
|
||||||
<Box justifyContent="space-between">
|
<Box justifyContent="space-between">
|
||||||
<Box />
|
<Box />
|
||||||
|
|||||||
Reference in New Issue
Block a user