From cc9773b34e14c309da5e37b7b2e830259295a689 Mon Sep 17 00:00:00 2001 From: butelo Date: Mon, 1 Dec 2025 02:49:38 +0100 Subject: [PATCH] feat(tui): add circular wrap-around navigation to all menus (#82) Co-authored-by: xes garcia --- packages/coding-agent/src/tui/model-selector.ts | 8 ++++---- packages/coding-agent/src/tui/user-message-selector.ts | 8 ++++---- packages/tui/src/components/select-list.ts | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/coding-agent/src/tui/model-selector.ts b/packages/coding-agent/src/tui/model-selector.ts index 7c0e4164..e16e64f7 100644 --- a/packages/coding-agent/src/tui/model-selector.ts +++ b/packages/coding-agent/src/tui/model-selector.ts @@ -185,14 +185,14 @@ export class ModelSelectorComponent extends Container { } handleInput(keyData: string): void { - // Up arrow + // Up arrow - wrap to bottom when at top if (keyData === "\x1b[A") { - this.selectedIndex = Math.max(0, this.selectedIndex - 1); + this.selectedIndex = this.selectedIndex === 0 ? this.filteredModels.length - 1 : this.selectedIndex - 1; this.updateList(); } - // Down arrow + // Down arrow - wrap to top when at bottom else if (keyData === "\x1b[B") { - this.selectedIndex = Math.min(this.filteredModels.length - 1, this.selectedIndex + 1); + this.selectedIndex = this.selectedIndex === this.filteredModels.length - 1 ? 0 : this.selectedIndex + 1; this.updateList(); } // Enter diff --git a/packages/coding-agent/src/tui/user-message-selector.ts b/packages/coding-agent/src/tui/user-message-selector.ts index ff1f3596..1d9d7bfe 100644 --- a/packages/coding-agent/src/tui/user-message-selector.ts +++ b/packages/coding-agent/src/tui/user-message-selector.ts @@ -78,13 +78,13 @@ class UserMessageList implements Component { } handleInput(keyData: string): void { - // Up arrow - go to previous (older) message + // Up arrow - go to previous (older) message, wrap to bottom when at top if (keyData === "\x1b[A") { - this.selectedIndex = Math.max(0, this.selectedIndex - 1); + this.selectedIndex = this.selectedIndex === 0 ? this.messages.length - 1 : this.selectedIndex - 1; } - // Down arrow - go to next (newer) message + // Down arrow - go to next (newer) message, wrap to top when at bottom else if (keyData === "\x1b[B") { - this.selectedIndex = Math.min(this.messages.length - 1, this.selectedIndex + 1); + this.selectedIndex = this.selectedIndex === this.messages.length - 1 ? 0 : this.selectedIndex + 1; } // Enter - select message and branch else if (keyData === "\r") { diff --git a/packages/tui/src/components/select-list.ts b/packages/tui/src/components/select-list.ts index fdf4f895..c06ceee6 100644 --- a/packages/tui/src/components/select-list.ts +++ b/packages/tui/src/components/select-list.ts @@ -145,14 +145,14 @@ export class SelectList implements Component { } handleInput(keyData: string): void { - // Up arrow + // Up arrow - wrap to bottom when at top if (keyData === "\x1b[A") { - this.selectedIndex = Math.max(0, this.selectedIndex - 1); + this.selectedIndex = this.selectedIndex === 0 ? this.filteredItems.length - 1 : this.selectedIndex - 1; this.notifySelectionChange(); } - // Down arrow + // Down arrow - wrap to top when at bottom else if (keyData === "\x1b[B") { - this.selectedIndex = Math.min(this.filteredItems.length - 1, this.selectedIndex + 1); + this.selectedIndex = this.selectedIndex === this.filteredItems.length - 1 ? 0 : this.selectedIndex + 1; this.notifySelectionChange(); } // Enter