1use crate::app::AppState;
2use crate::app::InputMode;
3
4impl AppState<'_> {
5 pub fn show_help(&mut self) {
6 self.help_scroll = 0;
7
8 self.help_text = "FILE OPERATIONS:\n\
9 :w - Save file\n\
10 :wq, :x - Save and quit\n\
11 :q - Quit (will warn if unsaved changes)\n\
12 :q! - Force quit without saving\n\n\
13 NAVIGATION:\n\
14 :[cell] - Jump to cell (e.g., :B10)\n\
15 hjkl - Move cursor (left, down, up, right)\n\
16 0 - Jump to first column\n\
17 ^ - Jump to first non-empty column\n\
18 $ - Jump to last column\n\
19 gg - Jump to first row\n\
20 G - Jump to last row\n\
21 Ctrl+arrows - Jump to next non-empty cell\n\
22 [ - Switch to previous sheet\n\
23 ] - Switch to next sheet\n\
24 :sheet [name/number] - Switch to sheet by name or index\n\n\
25 EDITING:\n\
26 Enter - Edit current cell\n\
27 :y - Copy current cell\n\
28 :d - Cut current cell\n\
29 :put, :pu - Paste to current cell\n\
30 u - Undo last operation\n\
31 Ctrl+r - Redo last undone operation\n\n\
32 SEARCH:\n\
33 / - Search forward\n\
34 ? - Search backward\n\
35 n - Jump to next search result\n\
36 N - Jump to previous search result\n\
37 :nohlsearch, :noh - Disable search highlighting\n\n\
38 COLUMN OPERATIONS:\n\
39 :cw fit - Adjust width of current column to fit its content\n\
40 :cw fit all - Adjust width of all columns to fit their content\n\
41 :cw min - Set current column width to minimum (5 characters)\n\
42 :cw min all - Set all columns width to minimum\n\
43 :cw [number] - Set current column width to specific number of characters\n\
44 :dc - Delete current column\n\
45 :dc [col] - Delete specific column (e.g., :dc A or :dc 1)\n\
46 :dc [start] [end] - Delete columns from start to end (e.g., :dc A C)\n\n\
47 ROW OPERATIONS:\n\
48 :dr - Delete current row\n\
49 :dr [row] - Delete specific row\n\
50 :dr [start] [end] - Delete rows from start to end\n\n\
51 EXPORT:\n\
52 :ej [h|v] [rows] - Export current sheet to JSON\n\
53 :eja [h|v] [rows] - Export all sheets to a single JSON file\n\
54 h=horizontal (default), v=vertical\n\
55 [rows]=number of header rows (default: 1)\n\n\
56 SHEET OPERATIONS:\n\
57 :addsheet [name] - Add a new sheet after the current sheet\n\
58 :delsheet - Delete the current sheet\n\n\
59 UI ADJUSTMENTS:\n\
60 +/= - Increase info panel height\n\
61 - - Decrease info panel height\n\n\
62 EDITING MODE:\n\
63 Esc - Exit Vim mode and save changes\n\
64 i - Enter Insert mode\n\
65 v - Enter Visual mode\n\
66 y - Yank (copy) text in Visual mode or with operator\n\
67 d - Delete text in Visual mode or with operator\n\
68 c - Change text in Visual mode or with operator\n\
69 p - Paste yanked or deleted text\n\
70 u - Undo last change\n\
71 Ctrl+r - Redo last undone change\n\
72 h,j,k,l - Move cursor left, down, up, right\n\
73 w - Move to next word\n\
74 b - Move to beginning of word\n\
75 e - Move to end of word\n\
76 $ - Move to end of line\n\
77 ^ - Move to first non-blank character of line\n\
78 gg - Move to first line\n\
79 G - Move to last line\n\
80 x - Delete character under cursor\n\
81 D - Delete to end of line\n\
82 C - Change to end of line\n\
83 o - Open new line below and enter Insert mode\n\
84 O - Open new line above and enter Insert mode\n\
85 A - Append at end of line\n\
86 I - Insert at beginning of line"
87 .to_string();
88
89 self.input_mode = InputMode::Help;
90 }
91
92 pub fn save_and_exit(&mut self) {
93 if !self.workbook.is_modified() {
94 self.add_notification("No changes to save".to_string());
95 self.should_quit = true;
96 return;
97 }
98
99 match self.workbook.save() {
100 Ok(_) => {
101 self.undo_history.clear();
102 self.add_notification("File saved".to_string());
103 self.should_quit = true;
104 }
105 Err(e) => {
106 self.add_notification(format!("Save failed: {e}"));
107 self.input_mode = InputMode::Normal;
108 }
109 }
110 }
111
112 pub fn save(&mut self) -> Result<(), anyhow::Error> {
113 if !self.workbook.is_modified() {
114 self.add_notification("No changes to save".to_string());
115 return Ok(());
116 }
117
118 match self.workbook.save() {
119 Ok(_) => {
120 self.undo_history.clear();
121 self.add_notification("File saved".to_string());
122 }
123 Err(e) => {
124 self.add_notification(format!("Save failed: {e}"));
125 }
126 }
127 Ok(())
128 }
129
130 pub fn exit_without_saving(&mut self) {
131 self.should_quit = true;
132 }
133}