1pub struct HelpEntry {
2 pub keys: &'static str,
3 pub description: &'static str,
4}
5
6pub struct HelpSection {
7 pub title: &'static str,
8 pub entries: &'static [HelpEntry],
9}
10
11pub const LEFT_HELP_SECTIONS: &[HelpSection] = &[
12 HelpSection {
13 title: "NAVIGATION",
14 entries: &[
15 HelpEntry {
16 keys: "h j k l / arrows",
17 description: "Move cell",
18 },
19 HelpEntry {
20 keys: "[ / ]",
21 description: "Switch sheet",
22 },
23 HelpEntry {
24 keys: "gg / G",
25 description: "Start/end of data",
26 },
27 HelpEntry {
28 keys: "0 / ^ / $",
29 description: "Row start / first non-empty / end",
30 },
31 HelpEntry {
32 keys: "Ctrl+arrows",
33 description: "Jump to next non-empty cell",
34 },
35 ],
36 },
37 HelpSection {
38 title: "SEARCH",
39 entries: &[
40 HelpEntry {
41 keys: "/",
42 description: "Search forward",
43 },
44 HelpEntry {
45 keys: "?",
46 description: "Search backward",
47 },
48 HelpEntry {
49 keys: "n / N",
50 description: "Next/previous search result",
51 },
52 HelpEntry {
53 keys: ":noh / :nohlsearch",
54 description: "Disable search highlighting",
55 },
56 ],
57 },
58 HelpSection {
59 title: "JUMP & SHEETS",
60 entries: &[
61 HelpEntry {
62 keys: ":<cell>",
63 description: "Jump to cell, e.g. :B10",
64 },
65 HelpEntry {
66 keys: ":sheet <name|index>",
67 description: "Switch sheet",
68 },
69 HelpEntry {
70 keys: ":addsheet <name>",
71 description: "Add sheet after current",
72 },
73 HelpEntry {
74 keys: ":delsheet",
75 description: "Delete current sheet",
76 },
77 ],
78 },
79 HelpSection {
80 title: "ROWS & COLUMNS",
81 entries: &[
82 HelpEntry {
83 keys: ":cw fit",
84 description: "Fit current column",
85 },
86 HelpEntry {
87 keys: ":cw fit all",
88 description: "Fit all columns",
89 },
90 HelpEntry {
91 keys: ":cw min",
92 description: "Minimize current column",
93 },
94 HelpEntry {
95 keys: ":cw min all",
96 description: "Minimize all columns",
97 },
98 HelpEntry {
99 keys: ":cw <number>",
100 description: "Set current column width",
101 },
102 HelpEntry {
103 keys: ":dr / :dr <row>",
104 description: "Delete current/specific row",
105 },
106 HelpEntry {
107 keys: ":dr <start> <end>",
108 description: "Delete row range",
109 },
110 HelpEntry {
111 keys: ":dc / :dc <col>",
112 description: "Delete current/specific column",
113 },
114 HelpEntry {
115 keys: ":dc <start> <end>",
116 description: "Delete column range",
117 },
118 HelpEntry {
119 keys: ":freeze [cell]",
120 description: "Freeze panes at cell",
121 },
122 HelpEntry {
123 keys: ":unfreeze",
124 description: "Clear frozen panes",
125 },
126 ],
127 },
128];
129
130pub const RIGHT_HELP_SECTIONS: &[HelpSection] = &[
131 HelpSection {
132 title: "ACTIONS",
133 entries: &[
134 HelpEntry {
135 keys: "Enter",
136 description: "Edit cell",
137 },
138 HelpEntry {
139 keys: "y / :y",
140 description: "Copy current cell",
141 },
142 HelpEntry {
143 keys: "d / :d",
144 description: "Cut current cell",
145 },
146 HelpEntry {
147 keys: "p / :put / :pu",
148 description: "Paste to current cell",
149 },
150 HelpEntry {
151 keys: "u",
152 description: "Undo",
153 },
154 HelpEntry {
155 keys: "Ctrl+r",
156 description: "Redo",
157 },
158 HelpEntry {
159 keys: "+ / = / -",
160 description: "Resize info panel",
161 },
162 ],
163 },
164 HelpSection {
165 title: "FILE & APP",
166 entries: &[
167 HelpEntry {
168 keys: ":w",
169 description: "Save file",
170 },
171 HelpEntry {
172 keys: ":wq / :x",
173 description: "Save and quit",
174 },
175 HelpEntry {
176 keys: ":q",
177 description: "Quit, warn if unsaved",
178 },
179 HelpEntry {
180 keys: ":q!",
181 description: "Force quit without saving",
182 },
183 HelpEntry {
184 keys: ":help",
185 description: "Show this overlay",
186 },
187 ],
188 },
189 HelpSection {
190 title: "EXPORT",
191 entries: &[
192 HelpEntry {
193 keys: ":ej",
194 description: "Export current sheet JSON",
195 },
196 HelpEntry {
197 keys: ":ej <h|v> <rows>",
198 description: "Export with header direction/count",
199 },
200 HelpEntry {
201 keys: ":eja",
202 description: "Export all sheets JSON",
203 },
204 HelpEntry {
205 keys: ":eja <h|v> <rows>",
206 description: "Export all with header settings",
207 },
208 ],
209 },
210 HelpSection {
211 title: "EDIT MODE",
212 entries: &[
213 HelpEntry {
214 keys: "Esc",
215 description: "Save edits and return",
216 },
217 HelpEntry {
218 keys: "i / v",
219 description: "Insert / visual mode",
220 },
221 HelpEntry {
222 keys: "h j k l",
223 description: "Move cursor",
224 },
225 HelpEntry {
226 keys: "w / b / e",
227 description: "Word navigation",
228 },
229 HelpEntry {
230 keys: "^ / $",
231 description: "Line start / end",
232 },
233 HelpEntry {
234 keys: "gg / G",
235 description: "First / last line",
236 },
237 HelpEntry {
238 keys: "x / D / C",
239 description: "Delete/change text",
240 },
241 HelpEntry {
242 keys: "y / d / c",
243 description: "Operator commands",
244 },
245 HelpEntry {
246 keys: "p / u / Ctrl+r",
247 description: "Paste / undo / redo",
248 },
249 HelpEntry {
250 keys: "o / O / A / I",
251 description: "Open or insert at line edges",
252 },
253 ],
254 },
255 HelpSection {
256 title: "HELP CONTROLS",
257 entries: &[
258 HelpEntry {
259 keys: "Esc / q / Enter",
260 description: "Close overlay",
261 },
262 HelpEntry {
263 keys: "j / k / arrows",
264 description: "Scroll one line",
265 },
266 HelpEntry {
267 keys: "PgUp / PgDn",
268 description: "Scroll one page",
269 },
270 HelpEntry {
271 keys: "Home / End",
272 description: "Jump to top/bottom",
273 },
274 ],
275 },
276];
277
278pub fn help_reference_line_count() -> usize {
279 column_line_count(LEFT_HELP_SECTIONS) + column_line_count(RIGHT_HELP_SECTIONS) + 1
280}
281
282pub fn help_reference_text() -> String {
283 let mut lines = Vec::new();
284
285 for section in LEFT_HELP_SECTIONS.iter().chain(RIGHT_HELP_SECTIONS.iter()) {
286 lines.push(section.title.to_string());
287 for entry in section.entries {
288 lines.push(format!("{} - {}", entry.keys, entry.description));
289 }
290 lines.push(String::new());
291 }
292
293 lines.join("\n")
294}
295
296fn column_line_count(sections: &[HelpSection]) -> usize {
297 sections
298 .iter()
299 .map(|section| section.entries.len() + 2)
300 .sum::<usize>()
301 .saturating_sub(1)
302}