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