feat(tui): add Ctrl+↑/↓ shortcuts to resize chat/thinking split
- Update help UI to show “Ctrl+↑/↓ → resize chat/thinking split”. - Introduce `ensure_ratio_bounds` and `nudge_ratio` on `LayoutNode` to clamp and adjust split ratios. - Ensure vertical split favors the thinking panel when it becomes focused. - Add `adjust_vertical_split` method in `ChatApp` and handle Ctrl+↑/↓ in normal mode to modify the split and update status messages.
This commit is contained in:
@@ -2407,6 +2407,12 @@ impl ChatApp {
|
||||
} else if !order.contains(&self.focused_panel) {
|
||||
self.focused_panel = order[0];
|
||||
}
|
||||
if let FocusedPanel::Thinking = self.focused_panel {
|
||||
// Ensure the vertical split favours thinking panel if chat collapsed entirely
|
||||
if let Some(tab) = self.workspace_mut().active_tab_mut() {
|
||||
tab.root.ensure_ratio_bounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cycle_focus_forward(&mut self) {
|
||||
@@ -2461,6 +2467,12 @@ impl ChatApp {
|
||||
configure_textarea_defaults(&mut self.textarea);
|
||||
}
|
||||
|
||||
pub fn adjust_vertical_split(&mut self, delta: f32) {
|
||||
if let Some(tab) = self.workspace_mut().active_tab_mut() {
|
||||
tab.root.nudge_ratio(delta);
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_slash_submission(&mut self) -> Result<SlashOutcome> {
|
||||
let raw = self.controller.input_buffer().text().to_string();
|
||||
if raw.trim().is_empty() {
|
||||
@@ -4169,6 +4181,16 @@ impl ChatApp {
|
||||
key.code,
|
||||
KeyCode::Right | KeyCode::Char('l') | KeyCode::Char('L')
|
||||
);
|
||||
let is_resize_up = key.modifiers.contains(KeyModifiers::CONTROL)
|
||||
&& matches!(
|
||||
key.code,
|
||||
KeyCode::Up | KeyCode::Char('k') | KeyCode::Char('K')
|
||||
);
|
||||
let is_resize_down = key.modifiers.contains(KeyModifiers::CONTROL)
|
||||
&& matches!(
|
||||
key.code,
|
||||
KeyCode::Down | KeyCode::Char('j') | KeyCode::Char('J')
|
||||
);
|
||||
|
||||
if is_reveal_active && matches!(self.mode, InputMode::Normal) {
|
||||
self.reveal_active_file();
|
||||
@@ -4208,6 +4230,21 @@ impl ChatApp {
|
||||
return Ok(AppState::Running);
|
||||
}
|
||||
|
||||
if (is_resize_up || is_resize_down) && matches!(self.mode, InputMode::Normal) {
|
||||
let delta = if is_resize_up { -0.05 } else { 0.05 };
|
||||
self.adjust_vertical_split(delta);
|
||||
self.status = format!(
|
||||
"Vertical split adjusted ({})",
|
||||
if delta.is_sign_positive() {
|
||||
"down"
|
||||
} else {
|
||||
"up"
|
||||
}
|
||||
);
|
||||
self.error = None;
|
||||
return Ok(AppState::Running);
|
||||
}
|
||||
|
||||
if is_symbol_search_key && matches!(self.mode, InputMode::Normal) {
|
||||
self.set_input_mode(InputMode::SymbolSearch);
|
||||
self.symbol_search.clear_query();
|
||||
|
||||
@@ -85,6 +85,31 @@ pub enum LayoutNode {
|
||||
}
|
||||
|
||||
impl LayoutNode {
|
||||
pub fn ensure_ratio_bounds(&mut self) {
|
||||
match self {
|
||||
LayoutNode::Split {
|
||||
ratio,
|
||||
first,
|
||||
second,
|
||||
..
|
||||
} => {
|
||||
*ratio = ratio.clamp(0.1, 0.9);
|
||||
first.ensure_ratio_bounds();
|
||||
second.ensure_ratio_bounds();
|
||||
}
|
||||
LayoutNode::Leaf(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nudge_ratio(&mut self, delta: f32) {
|
||||
match self {
|
||||
LayoutNode::Split { ratio, .. } => {
|
||||
*ratio = (*ratio + delta).clamp(0.1, 0.9);
|
||||
}
|
||||
LayoutNode::Leaf(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_leaf(&mut self, target: PaneId, replacement: LayoutNode) -> bool {
|
||||
match self {
|
||||
LayoutNode::Leaf(id) => {
|
||||
|
||||
@@ -3070,6 +3070,7 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) {
|
||||
Line::from(" :h, :help → open help from command mode"),
|
||||
Line::from(" :files, :explorer → toggle files panel"),
|
||||
Line::from(" Ctrl+←/→ → resize files panel"),
|
||||
Line::from(" Ctrl+↑/↓ → resize chat/thinking split"),
|
||||
],
|
||||
1 => vec![
|
||||
// Editing
|
||||
@@ -3183,6 +3184,7 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) {
|
||||
Line::from(" F1 or ? → toggle help overlay"),
|
||||
Line::from(" :files, :explorer → toggle files panel"),
|
||||
Line::from(" Ctrl+←/→ → resize files panel"),
|
||||
Line::from(" Ctrl+↑/↓ → resize chat/thinking split"),
|
||||
Line::from(" :quit → quit application"),
|
||||
Line::from(" Ctrl+C twice → quit application"),
|
||||
Line::from(" :reload → reload configuration and themes"),
|
||||
|
||||
Reference in New Issue
Block a user