Skip to main content

fresh/app/
view_actions.rs

1//! View mode action handlers.
2//!
3//! This module contains handlers for view-related actions like compose mode toggling.
4
5use super::Editor;
6use crate::state::ViewMode;
7use rust_i18n::t;
8
9impl Editor {
10    /// Toggle between Compose and Source view modes.
11    pub fn handle_toggle_compose_mode(&mut self) {
12        let default_wrap = self.config.editor.line_wrap;
13        let default_line_numbers = self.config.editor.line_numbers;
14        let active_split = self.split_manager.active_split();
15
16        let mut view_mode = {
17            if let Some(vs) = self.split_view_states.get(&active_split) {
18                vs.view_mode.clone()
19            } else {
20                self.active_state().view_mode.clone()
21            }
22        };
23
24        view_mode = match view_mode {
25            ViewMode::Compose => ViewMode::Source,
26            _ => ViewMode::Compose,
27        };
28
29        // Update split view state
30        let current_line_numbers = self.active_state().margins.show_line_numbers;
31        if let Some(vs) = self.split_view_states.get_mut(&active_split) {
32            vs.view_mode = view_mode.clone();
33            // In Compose mode, disable builtin line wrap - the plugin handles
34            // wrapping by inserting Break tokens in the view transform pipeline.
35            // In Source mode, respect the user's default_wrap preference.
36            vs.viewport.line_wrap_enabled = match view_mode {
37                ViewMode::Compose => false,
38                ViewMode::Source => default_wrap,
39            };
40            match view_mode {
41                ViewMode::Compose => {
42                    vs.compose_prev_line_numbers = Some(current_line_numbers);
43                    self.active_state_mut().margins.set_line_numbers(false);
44                }
45                ViewMode::Source => {
46                    // Clear compose width to remove margins
47                    vs.compose_width = None;
48                    vs.view_transform = None;
49                    let restore = vs
50                        .compose_prev_line_numbers
51                        .take()
52                        .unwrap_or(default_line_numbers);
53                    self.active_state_mut().margins.set_line_numbers(restore);
54                }
55            }
56        }
57
58        // Keep buffer-level view mode for status/use
59        {
60            let state = self.active_state_mut();
61            state.view_mode = view_mode.clone();
62            // Note: viewport.line_wrap_enabled is now handled in SplitViewState above
63            // Clear compose state when switching to Source mode
64            if matches!(view_mode, ViewMode::Source) {
65                state.compose_width = None;
66                state.view_transform = None;
67            }
68        }
69
70        let mode_label = match view_mode {
71            ViewMode::Compose => t!("view.compose").to_string(),
72            ViewMode::Source => "Source".to_string(),
73        };
74        self.set_status_message(t!("view.mode", mode = mode_label).to_string());
75    }
76}