Skip to main content

fresh/app/
help_actions.rs

1//! Help-buffer orchestrators on `Editor`.
2//!
3//! `open_help_manual` and `open_keyboard_shortcuts` create read-only
4//! virtual buffers populated with the manual text or keybinding listing.
5//! Both check for an existing help buffer first to avoid duplicates.
6
7use super::help;
8use super::Editor;
9
10impl Editor {
11    /// Open the built-in help manual in a read-only buffer
12    ///
13    /// If a help manual buffer already exists, switch to it instead of creating a new one.
14    pub fn open_help_manual(&mut self) {
15        // Check if help buffer already exists
16        let existing_buffer = self
17            .buffer_metadata
18            .iter()
19            .find(|(_, m)| m.display_name == help::HELP_MANUAL_BUFFER_NAME)
20            .map(|(id, _)| *id);
21
22        if let Some(buffer_id) = existing_buffer {
23            // Switch to existing help buffer
24            self.set_active_buffer(buffer_id);
25            return;
26        }
27
28        // Create new help buffer with "special" mode (has 'q' to close)
29        let buffer_id = self.create_virtual_buffer(
30            help::HELP_MANUAL_BUFFER_NAME.to_string(),
31            "special".to_string(),
32            true,
33        );
34
35        // Set the content
36        if let Some(state) = self.buffers.get_mut(&buffer_id) {
37            state.buffer.insert(0, help::HELP_MANUAL_CONTENT);
38            state.buffer.clear_modified();
39            state.editing_disabled = true;
40
41            // Disable line numbers for cleaner display
42            state.margins.configure_for_line_numbers(false);
43        }
44
45        self.set_active_buffer(buffer_id);
46    }
47
48    /// Open the keyboard shortcuts viewer in a read-only buffer
49    ///
50    /// If a keyboard shortcuts buffer already exists, switch to it instead of creating a new one.
51    /// The shortcuts are dynamically generated from the current keybindings configuration.
52    pub fn open_keyboard_shortcuts(&mut self) {
53        // Check if keyboard shortcuts buffer already exists
54        let existing_buffer = self
55            .buffer_metadata
56            .iter()
57            .find(|(_, m)| m.display_name == help::KEYBOARD_SHORTCUTS_BUFFER_NAME)
58            .map(|(id, _)| *id);
59
60        if let Some(buffer_id) = existing_buffer {
61            // Switch to existing buffer
62            self.set_active_buffer(buffer_id);
63            return;
64        }
65
66        // Get all keybindings
67        let bindings = self.keybindings.read().unwrap().get_all_bindings();
68
69        // Format the keybindings as readable text
70        let mut content = String::from("Keyboard Shortcuts\n");
71        content.push_str("==================\n\n");
72        content.push_str("Press 'q' to close this buffer.\n\n");
73
74        // Group bindings by context (Normal, Prompt, etc.)
75        let mut current_context = String::new();
76        for (key, action) in &bindings {
77            // Check if action starts with a context prefix like "[Prompt] "
78            let (context, action_name) = if let Some(bracket_end) = action.find("] ") {
79                let ctx = &action[1..bracket_end];
80                let name = &action[bracket_end + 2..];
81                (ctx.to_string(), name.to_string())
82            } else {
83                ("Normal".to_string(), action.clone())
84            };
85
86            // Print context header when it changes
87            if context != current_context {
88                if !current_context.is_empty() {
89                    content.push('\n');
90                }
91                content.push_str(&format!("── {} Mode ──\n\n", context));
92                current_context = context;
93            }
94
95            // Format: "  Ctrl+S          Save"
96            content.push_str(&format!("  {:20} {}\n", key, action_name));
97        }
98
99        // Create new keyboard shortcuts buffer with "special" mode (has 'q' to close)
100        let buffer_id = self.create_virtual_buffer(
101            help::KEYBOARD_SHORTCUTS_BUFFER_NAME.to_string(),
102            "special".to_string(),
103            true,
104        );
105
106        // Set the content
107        if let Some(state) = self.buffers.get_mut(&buffer_id) {
108            state.buffer.insert(0, &content);
109            state.buffer.clear_modified();
110            state.editing_disabled = true;
111
112            // Disable line numbers for cleaner display
113            state.margins.configure_for_line_numbers(false);
114        }
115
116        self.set_active_buffer(buffer_id);
117    }
118}