commit da48bf7b7ec3e34411a8e24569f259c9f7a7d3f4
parent e9ba8fbada4a14ae1d491eecfb7b622d5eae9c2e
Author: William Casarin <jb55@jb55.com>
Date: Thu, 26 Feb 2026 11:53:11 -0800
dave: make session keybindings match visual order
Ctrl+1-9 and prev/next cycling now use the visual display order
(host groups alphabetically, then chats) instead of recency order,
so keybinding numbers always go 1, 2, 3... top to bottom in the
session list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
3 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/crates/notedeck_dave/src/session.rs b/crates/notedeck_dave/src/session.rs
@@ -833,6 +833,17 @@ impl SessionManager {
&self.chat_ids
}
+ /// Session IDs in visual/display order (host groups then chats).
+ /// Keybinding numbers (Ctrl+1-9) map to this order.
+ pub fn visual_order(&self) -> Vec<SessionId> {
+ let mut ids = Vec::new();
+ for (_, group_ids) in &self.host_groups {
+ ids.extend_from_slice(group_ids);
+ }
+ ids.extend_from_slice(&self.chat_ids);
+ ids
+ }
+
/// Get a session's index in the recency-ordered list (for keyboard shortcuts).
pub fn session_index(&self, id: SessionId) -> Option<usize> {
self.order.iter().position(|&oid| oid == id)
diff --git a/crates/notedeck_dave/src/ui/session_list.rs b/crates/notedeck_dave/src/ui/session_list.rs
@@ -92,6 +92,7 @@ impl<'a> SessionListUi<'a> {
fn sessions_list_ui(&self, ui: &mut egui::Ui) -> Option<SessionListAction> {
let mut action = None;
let active_id = self.session_manager.active_id();
+ let mut visual_index: usize = 0;
// Agents grouped by hostname (pre-computed, no per-frame allocation)
for (hostname, ids) in self.session_manager.host_groups() {
@@ -108,10 +109,11 @@ impl<'a> SessionListUi<'a> {
ui.add_space(4.0);
for &id in ids {
if let Some(session) = self.session_manager.get(id) {
- let index = self.session_manager.session_index(id).unwrap_or(0);
- if let Some(a) = self.render_session_item(ui, session, index, active_id) {
+ if let Some(a) = self.render_session_item(ui, session, visual_index, active_id)
+ {
action = Some(a);
}
+ visual_index += 1;
}
}
ui.add_space(8.0);
@@ -128,10 +130,11 @@ impl<'a> SessionListUi<'a> {
ui.add_space(4.0);
for &id in chat_ids {
if let Some(session) = self.session_manager.get(id) {
- let index = self.session_manager.session_index(id).unwrap_or(0);
- if let Some(a) = self.render_session_item(ui, session, index, active_id) {
+ if let Some(a) = self.render_session_item(ui, session, visual_index, active_id)
+ {
action = Some(a);
}
+ visual_index += 1;
}
}
}
diff --git a/crates/notedeck_dave/src/update.rs b/crates/notedeck_dave/src/update.rs
@@ -406,14 +406,14 @@ pub fn switch_and_focus_session(
}
}
-/// Switch to agent by index in the ordered list (0-indexed).
+/// Switch to agent by index in the visual display order (0-indexed).
pub fn switch_to_agent_by_index(
session_manager: &mut SessionManager,
scene: &mut AgentScene,
show_scene: bool,
index: usize,
) {
- let ids = session_manager.session_ids();
+ let ids = session_manager.visual_order();
if let Some(&id) = ids.get(index) {
switch_and_focus_session(session_manager, scene, show_scene, id);
}
@@ -426,7 +426,7 @@ fn cycle_agent(
show_scene: bool,
index_fn: impl FnOnce(usize, usize) -> usize,
) {
- let ids = session_manager.session_ids();
+ let ids = session_manager.visual_order();
if ids.is_empty() {
return;
}