From 2b1d308446dd67430cdb4a7993ad06af42c57721 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 23:12:36 +0000 Subject: [PATCH] add full-screen toggle for embedded editor pane - add ToggleEditorFullscreen action variant - add editor_fullscreen bool to DualPane; draw() gives 100% width to the active pane when true - clear editor_fullscreen on SwitchPane and close_editor_in_active - intercept Ctrl+E before EditorKeyInput routing in app map_key() - dispatch ToggleEditorFullscreen: toggle the flag when active pane is an editor, no-op otherwise - update draw_command_bar signature with editor_fullscreen param; show Ctrl+E:Fullscreen in normal editor mode and Ctrl+E:Exit fullscreen while fullscreen is active https://claude.ai/code/session_011dpJMJEWrqscYNKheGcwj2 --- src/action.rs | 2 ++ src/app.rs | 13 +++++++++++- src/components/command_bar.rs | 38 ++++++++++++++++++++++++++--------- src/components/dual_pane.rs | 20 ++++++++++++++++++ 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/action.rs b/src/action.rs index 5d93713..a747283 100644 --- a/src/action.rs +++ b/src/action.rs @@ -89,6 +89,8 @@ pub enum Action { ThemeEditorOpenPicker, ThemeEditorPickerLeft, ThemeEditorPickerRight, + /// Toggle the active editor pane to fill the entire dual-pane area. + ToggleEditorFullscreen, // Task runner TaskLine(String), TaskComplete(i32), diff --git a/src/app.rs b/src/app.rs index bdf4d1a..7b2a7d3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -143,11 +143,13 @@ impl App { self.dual_pane.draw(frame, chunks[0], &self.theme); draw_status_bar(frame, chunks[1], &self.dual_pane, &self.input_mode, &self.theme); let active_editor = self.dual_pane.active_editor().is_some(); + let editor_fullscreen = self.dual_pane.editor_fullscreen; draw_command_bar( frame, chunks[2], &self.input_mode, active_editor, + editor_fullscreen, self.task.as_ref(), &self.theme, ); @@ -255,8 +257,12 @@ impl App { InputMode::Normal => {} } - // If the active pane is an editor, route all remaining keys into it. + // If the active pane is an editor, intercept the fullscreen toggle before + // routing everything else into the editor. if self.dual_pane.active_editor().is_some() { + if let (KeyModifiers::CONTROL, KeyCode::Char('e')) = (key.modifiers, key.code) { + return Action::ToggleEditorFullscreen; + } return Action::EditorKeyInput(key); } @@ -600,6 +606,11 @@ impl App { self.dual_pane.close_editor_in_active(); } } + Action::ToggleEditorFullscreen => { + if self.dual_pane.active_editor().is_some() { + self.dual_pane.editor_fullscreen = !self.dual_pane.editor_fullscreen; + } + } Action::EditorKeyInput(key) => { if let Some(inner_action) = self.dual_pane.handle_editor_key(key) { self.dispatch(inner_action); diff --git a/src/components/command_bar.rs b/src/components/command_bar.rs index fae5174..49d5ce1 100644 --- a/src/components/command_bar.rs +++ b/src/components/command_bar.rs @@ -13,6 +13,7 @@ pub fn draw_command_bar( area: Rect, input_mode: &InputMode, active_editor: bool, + editor_fullscreen: bool, task: Option<&TaskState>, theme: &Theme, ) { @@ -24,16 +25,33 @@ pub fn draw_command_bar( let line = match input_mode { InputMode::Normal => { if active_editor { - Line::from(vec![ - Span::styled("Ctrl+S", hint_style), - Span::raw(":Save "), - Span::styled("Ctrl+Q", hint_style), - Span::raw("/"), - Span::styled("Esc", hint_style), - Span::raw(":Close "), - Span::styled("Tab", hint_style), - Span::raw(":Switch pane"), - ]) + if editor_fullscreen { + Line::from(vec![ + Span::styled("Ctrl+S", hint_style), + Span::raw(":Save "), + Span::styled("Ctrl+Q", hint_style), + Span::raw("/"), + Span::styled("Esc", hint_style), + Span::raw(":Close "), + Span::styled("Tab", hint_style), + Span::raw(":Switch pane "), + Span::styled("Ctrl+E", hint_style), + Span::raw(":Exit fullscreen"), + ]) + } else { + Line::from(vec![ + Span::styled("Ctrl+S", hint_style), + Span::raw(":Save "), + Span::styled("Ctrl+Q", hint_style), + Span::raw("/"), + Span::styled("Esc", hint_style), + Span::raw(":Close "), + Span::styled("Tab", hint_style), + Span::raw(":Switch pane "), + Span::styled("Ctrl+E", hint_style), + Span::raw(":Fullscreen"), + ]) + } } else { let mut spans = vec![ Span::styled("F1", fkey_style), diff --git a/src/components/dual_pane.rs b/src/components/dual_pane.rs index bd999a7..4c223ed 100644 --- a/src/components/dual_pane.rs +++ b/src/components/dual_pane.rs @@ -37,6 +37,8 @@ pub struct DualPane { pub left: PaneContent, pub right: PaneContent, pub active: PaneSide, + /// When true, the active editor fills the whole dual-pane area. + pub editor_fullscreen: bool, } impl DualPane { @@ -45,6 +47,7 @@ impl DualPane { left: PaneContent::Explorer(Explorer::new(left_dir)), right: PaneContent::Explorer(Explorer::new(right_dir)), active, + editor_fullscreen: false, } } @@ -133,6 +136,7 @@ impl DualPane { PaneContent::Editor(e) => e.origin_dir.clone(), PaneContent::Explorer(_) => return, }; + self.editor_fullscreen = false; match self.active { PaneSide::Left => self.left = PaneContent::Explorer(Explorer::new(origin_dir)), PaneSide::Right => self.right = PaneContent::Explorer(Explorer::new(origin_dir)), @@ -150,6 +154,7 @@ impl DualPane { pub fn handle_action(&mut self, action: &Action) -> Option { match action { Action::SwitchPane => { + self.editor_fullscreen = false; self.active = match self.active { PaneSide::Left => PaneSide::Right, PaneSide::Right => PaneSide::Left, @@ -179,6 +184,21 @@ impl DualPane { } pub fn draw(&mut self, frame: &mut Frame, area: Rect, theme: &Theme) { + if self.editor_fullscreen { + // Give the entire area to the active pane (must be an editor). + match self.active { + PaneSide::Left => match &mut self.left { + PaneContent::Editor(e) => e.draw(frame, area, true, theme), + PaneContent::Explorer(e) => e.draw(frame, area, true, theme), + }, + PaneSide::Right => match &mut self.right { + PaneContent::Editor(e) => e.draw(frame, area, true, theme), + PaneContent::Explorer(e) => e.draw(frame, area, true, theme), + }, + } + return; + } + let chunks = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])