1use super::{HelpCategory, HelpEntry};
2
3pub static NORMAL_ENTRIES: &[HelpEntry] = &[
4 HelpEntry {
5 tags: &["count", "[count]", "N"],
6 category: HelpCategory::Normal,
7 summary: "Numeric count prefix",
8 detail: "Type digits before a motion or operator to repeat or scale it,\n\
9 vim-style. Examples: 5j moves 5 rows down, 10G jumps to row 10,\n\
10 3dd deletes 3 rows, 4yy yanks 4 rows, 2w hops 2 non-empty cells.\n\
11 The count is shown in the status line as you type.\n\n\
12 0 alone goes to the first column; only after a non-zero digit\n\
13 does 0 extend the count (so 10j really moves 10 rows).\n\n\
14 Esc cancels a partially-typed count. Counts apply to:\n\
15 h j k l, Up/Down/Left/Right, w b, gg G, dd yy.\n\n\
16 Operator-pending counts: you can also place a count between the\n\
17 operator and the motion (e.g. d3j, y2k). If both an outer count\n\
18 and an inner motion count are given they multiply: 5d2j clears\n\
19 10 rows downward from the cursor.",
20 },
21 HelpEntry {
22 tags: &["h"],
23 category: HelpCategory::Normal,
24 summary: "Move cursor left ([count]h)",
25 detail: "Move the cursor one column to the left. Stops at column A.\n\
26 With a count prefix, moves [count] columns.\n\
27 Alias: Left arrow",
28 },
29 HelpEntry {
30 tags: &["j"],
31 category: HelpCategory::Normal,
32 summary: "Move cursor down ([count]j)",
33 detail: "Move the cursor one row down. With a count prefix, moves\n\
34 [count] rows.\nAlias: Down arrow",
35 },
36 HelpEntry {
37 tags: &["k"],
38 category: HelpCategory::Normal,
39 summary: "Move cursor up ([count]k)",
40 detail: "Move the cursor one row up. Stops at row 1. With a count\n\
41 prefix, moves [count] rows.\nAlias: Up arrow",
42 },
43 HelpEntry {
44 tags: &["l"],
45 category: HelpCategory::Normal,
46 summary: "Move cursor right ([count]l)",
47 detail: "Move the cursor one column to the right. With a count prefix,\n\
48 moves [count] columns.\nAlias: Right arrow",
49 },
50 HelpEntry {
51 tags: &["gg"],
52 category: HelpCategory::Normal,
53 summary: "Go to first row / row N ([count]gg)",
54 detail: "Move the cursor to row 1, keeping the current column.\n\
55 With a count prefix, jumps to row [count] (1-indexed).",
56 },
57 HelpEntry {
58 tags: &["G"],
59 category: HelpCategory::Normal,
60 summary: "Go to last row / row N ([count]G)",
61 detail: "Move the cursor to the last row with data, keeping the\n\
62 current column. With a count prefix, jumps to row [count]\n\
63 (1-indexed) instead.",
64 },
65 HelpEntry {
66 tags: &["0"],
67 category: HelpCategory::Normal,
68 summary: "Go to first column",
69 detail: "Move the cursor to column A, keeping the current row.",
70 },
71 HelpEntry {
72 tags: &["$"],
73 category: HelpCategory::Normal,
74 summary: "Go to last column",
75 detail: "Move the cursor to the last column with data, keeping the current row.",
76 },
77 HelpEntry {
78 tags: &["w"],
79 category: HelpCategory::Normal,
80 summary: "Next non-empty cell ([count]w)",
81 detail: "Jump to the next non-empty cell to the right in the current\n\
82 row. With a count prefix, hops [count] non-empty cells.",
83 },
84 HelpEntry {
85 tags: &["b"],
86 category: HelpCategory::Normal,
87 summary: "Previous non-empty cell ([count]b)",
88 detail: "Jump to the previous non-empty cell to the left in the\n\
89 current row. With a count prefix, hops [count] non-empty\n\
90 cells back.",
91 },
92 HelpEntry {
93 tags: &["dd"],
94 category: HelpCategory::Normal,
95 summary: "Delete current row ([count]dd)",
96 detail: "Deletes all cells in the current row. With a count prefix,\n\
97 deletes [count] rows starting at the cursor; the deleted\n\
98 rows are stored line-wise in the register and can be\n\
99 pasted as a block with p (below) or P (above). Undoable\n\
100 with u.\n\n\
101 To clear a range using a motion instead of repeating the\n\
102 operator, use d{motion}: see dj, dk, dl, dh.",
103 },
104 HelpEntry {
105 tags: &["dj", "d3j"],
106 category: HelpCategory::Normal,
107 summary: "Clear rows downward (d[count]j)",
108 detail: "Clear the current row and [count] rows below it (content only;\n\
109 rows are not removed). Without a count, clears the current row\n\
110 and the one below. An outer count before d multiplies the motion\n\
111 count: 5d2j clears 10 rows. Undoable with u.",
112 },
113 HelpEntry {
114 tags: &["dk", "d2k"],
115 category: HelpCategory::Normal,
116 summary: "Clear rows upward (d[count]k)",
117 detail: "Clear [count] rows above the cursor and the current row\n\
118 (content only; rows are not removed). Without a count, clears\n\
119 the current row and the one above. Undoable with u.",
120 },
121 HelpEntry {
122 tags: &["dl"],
123 category: HelpCategory::Normal,
124 summary: "Clear cells rightward (d[count]l)",
125 detail: "Clear the current cell and [count] cells to the right.\n\
126 Without a count, clears the current cell and the one to its\n\
127 right. Undoable with u.",
128 },
129 HelpEntry {
130 tags: &["dh"],
131 category: HelpCategory::Normal,
132 summary: "Clear cells leftward (d[count]h)",
133 detail: "Clear [count] cells to the left and the current cell.\n\
134 Without a count, clears the cell to the left and the current\n\
135 cell. Undoable with u.",
136 },
137 HelpEntry {
138 tags: &["yy"],
139 category: HelpCategory::Normal,
140 summary: "Yank current row ([count]yy)",
141 detail: "Copies all cells in the current row to the register. With a\n\
142 count prefix, yanks [count] rows starting at the cursor.\n\
143 Paste with p (below) or P (above).\n\n\
144 To yank a range using a motion, use y{motion}: see yj, yk,\n\
145 yl, yh.",
146 },
147 HelpEntry {
148 tags: &["yj"],
149 category: HelpCategory::Normal,
150 summary: "Yank rows downward (y[count]j)",
151 detail: "Yank the current row and [count] rows below it into the register.\n\
152 Paste with p (below) or P (above). An outer count multiplies\n\
153 the motion count: 5y2j yanks 10 rows.",
154 },
155 HelpEntry {
156 tags: &["yk"],
157 category: HelpCategory::Normal,
158 summary: "Yank rows upward (y[count]k)",
159 detail: "Yank [count] rows above the cursor and the current row into the\n\
160 register. Paste with p (below) or P (above).",
161 },
162 HelpEntry {
163 tags: &["yl", "y3l", "y4l"],
164 category: HelpCategory::Normal,
165 summary: "Yank cells rightward (y[count]l)",
166 detail: "Yank the current cell and [count] cells to the right into the\n\
167 register. Without a count, yanks the current cell and the one\n\
168 to its right. Paste with p.",
169 },
170 HelpEntry {
171 tags: &["yh"],
172 category: HelpCategory::Normal,
173 summary: "Yank cells leftward (y[count]h)",
174 detail: "Yank [count] cells to the left and the current cell into the\n\
175 register. Without a count, yanks the cell to the left and the\n\
176 current cell. Paste with p.",
177 },
178 HelpEntry {
179 tags: &["x"],
180 category: HelpCategory::Normal,
181 summary: "Clear current cell",
182 detail: "Clears the content of the cell under the cursor. Undoable with u.",
183 },
184 HelpEntry {
185 tags: &["p"],
186 category: HelpCategory::Normal,
187 summary: "Paste below",
188 detail: "Paste the register contents below the current row (for row/block\nregisters) or into the cell below (for cell registers).\nFormula references are adjusted automatically.",
189 },
190 HelpEntry {
191 tags: &["P"],
192 category: HelpCategory::Normal,
193 summary: "Paste above",
194 detail: "Paste the register contents above the current row (for row/block\nregisters) or into the current cell (for cell registers).\nFormula references are adjusted automatically.",
195 },
196 HelpEntry {
197 tags: &["."],
198 category: HelpCategory::Normal,
199 summary: "Repeat last change",
200 detail: "Re-apply the last cell-mutating operation at the current cursor \
201 position. Works after x, dd, d (visual), p, P, and any edit committed from \
202 Insert mode (i/a/c + Esc or Enter). u and Ctrl-r do not affect \
203 the repeat register.",
204 },
205 HelpEntry {
206 tags: &["u"],
207 category: HelpCategory::Normal,
208 summary: "Undo",
209 detail: "Undo the last cell edit. Supports multiple levels of undo.",
210 },
211 HelpEntry {
212 tags: &["Ctrl+R"],
213 category: HelpCategory::Normal,
214 summary: "Redo",
215 detail: "Redo the last undone edit.",
216 },
217 HelpEntry {
218 tags: &["Ctrl+D"],
219 category: HelpCategory::Normal,
220 summary: "Half page down",
221 detail: "Move the cursor down by half the visible page height.",
222 },
223 HelpEntry {
224 tags: &["Ctrl+U"],
225 category: HelpCategory::Normal,
226 summary: "Half page up",
227 detail: "Move the cursor up by half the visible page height.",
228 },
229 HelpEntry {
230 tags: &["Ctrl+F"],
231 category: HelpCategory::Normal,
232 summary: "Page down",
233 detail: "Move the cursor down by one full page.",
234 },
235 HelpEntry {
236 tags: &["Ctrl+B"],
237 category: HelpCategory::Normal,
238 summary: "Page up",
239 detail: "Move the cursor up by one full page.",
240 },
241 HelpEntry {
242 tags: &["i", "a"],
243 category: HelpCategory::Normal,
244 summary: "Enter Insert mode",
245 detail: "Switch to Insert mode to edit the current cell.\ni places the cursor at the end of existing content.\na behaves the same as i in Cell.",
246 },
247 HelpEntry {
248 tags: &["o"],
249 category: HelpCategory::Normal,
250 summary: "Enter Insert mode (new line)",
251 detail: "Switch to Insert mode. In Cell, behaves the same as i\n(there are no multi-line cells).",
252 },
253 HelpEntry {
254 tags: &["Enter"],
255 category: HelpCategory::Normal,
256 summary: "Edit cell",
257 detail: "Enter Insert mode to edit the current cell. Same as i.",
258 },
259 HelpEntry {
260 tags: &["v"],
261 category: HelpCategory::Normal,
262 summary: "Enter Visual mode",
263 detail: "Start visual selection from the current cell. Use h/j/k/l to\nextend the selection. Press d to delete or y to yank.",
264 },
265 HelpEntry {
266 tags: &["Ctrl+V"],
267 category: HelpCategory::Normal,
268 summary: "Enter Visual Block mode",
269 detail: "Start block (rectangular) selection from the current cell.\nUse h/j/k/l to extend. Press d to delete or y to yank.",
270 },
271 HelpEntry {
272 tags: &["/"],
273 category: HelpCategory::Normal,
274 summary: "Search forward",
275 detail: "Open the forward-search prompt. Type a pattern and press Enter to\nfind the next cell whose value contains the pattern.\nCase-insensitive. Use n / N to step through matches.",
276 },
277 HelpEntry {
278 tags: &["?"],
279 category: HelpCategory::Normal,
280 summary: "Search backward",
281 detail: "Open the backward-search prompt. Type a pattern and press Enter\nto find the previous cell whose value contains the pattern.\nCase-insensitive. Use n / N to step through matches.",
282 },
283 HelpEntry {
284 tags: &["n"],
285 category: HelpCategory::Normal,
286 summary: "Next search match",
287 detail: "Jump to the next cell matching the last search pattern.",
288 },
289 HelpEntry {
290 tags: &["N"],
291 category: HelpCategory::Normal,
292 summary: "Previous search match",
293 detail: "Jump to the previous cell matching the last search pattern.",
294 },
295 HelpEntry {
296 tags: &["f"],
297 category: HelpCategory::Normal,
298 summary: "Find char in row (forward)",
299 detail: "After f, the next keypress is the target character. The cursor\njumps to the next non-empty cell in the current row whose displayed\nvalue starts with that character (case-insensitive).\nUse ; to repeat and , to repeat reversed.",
300 },
301 HelpEntry {
302 tags: &["F"],
303 category: HelpCategory::Normal,
304 summary: "Find char in row (backward)",
305 detail: "Like f, but searches the current row to the left of the cursor.",
306 },
307 HelpEntry {
308 tags: &[";"],
309 category: HelpCategory::Normal,
310 summary: "Repeat last find",
311 detail: "Repeat the last f / F find in the same direction.",
312 },
313 HelpEntry {
314 tags: &[","],
315 category: HelpCategory::Normal,
316 summary: "Repeat last find reversed",
317 detail: "Repeat the last f / F find in the opposite direction.",
318 },
319 HelpEntry {
320 tags: &["~", "tilde"],
321 category: HelpCategory::Normal,
322 summary: "Toggle case of first character",
323 detail: "Toggle the case of the first character of the current cell's value\n\
324 and advance the cursor one column to the right (vim `~` semantics\n\
325 scoped to one cell). No-op on formula cells.",
326 },
327 HelpEntry {
328 tags: &["guu"],
329 category: HelpCategory::Normal,
330 summary: "Lowercase entire cell",
331 detail: "Convert every character in the current cell's value to lowercase.\n\
332 No-op on formula cells. Undoable with u.",
333 },
334 HelpEntry {
335 tags: &["gUU"],
336 category: HelpCategory::Normal,
337 summary: "Uppercase entire cell",
338 detail: "Convert every character in the current cell's value to uppercase.\n\
339 No-op on formula cells. Undoable with u.",
340 },
341 HelpEntry {
342 tags: &["g~~"],
343 category: HelpCategory::Normal,
344 summary: "Toggle case of entire cell",
345 detail: "Toggle the case of every character in the current cell's value\n\
346 (uppercase ↔ lowercase). No-op on formula cells. Undoable with u.",
347 },
348 HelpEntry {
349 tags: &["Ctrl+A"],
350 category: HelpCategory::Normal,
351 summary: "Increment number under cursor ([count]Ctrl+A)",
352 detail: "Add 1 (or [count]) to the number stored in the current cell.\n\
353 Dependent formula cells are re-evaluated automatically.\n\
354 No-op if the cell contains a formula (shows an error message)\n\
355 or non-numeric text. Repeatable with '.'.",
356 },
357 HelpEntry {
358 tags: &["Ctrl+X"],
359 category: HelpCategory::Normal,
360 summary: "Decrement number under cursor ([count]Ctrl+X)",
361 detail: "Subtract 1 (or [count]) from the number stored in the current cell.\n\
362 Dependent formula cells are re-evaluated automatically.\n\
363 No-op if the cell contains a formula (shows an error message)\n\
364 or non-numeric text. Repeatable with '.'.",
365 },
366];
367
368pub static INSERT_ENTRIES: &[HelpEntry] = &[
369 HelpEntry {
370 tags: &["Esc"],
371 category: HelpCategory::Insert,
372 summary: "Confirm edit, return to Normal",
373 detail: "Saves the current cell content and returns to Normal mode.",
374 },
375 HelpEntry {
376 tags: &["Enter-insert"],
377 category: HelpCategory::Insert,
378 summary: "Confirm edit and move down",
379 detail: "Saves the current cell content and returns to Normal mode.\nIn Insert mode, Enter confirms the edit (same as Esc).",
380 },
381 HelpEntry {
382 tags: &["Backspace"],
383 category: HelpCategory::Insert,
384 summary: "Delete character before cursor",
385 detail: "Deletes the character to the left of the cursor in the cell\nedit buffer.",
386 },
387 HelpEntry {
388 tags: &["Delete"],
389 category: HelpCategory::Insert,
390 summary: "Delete character at cursor",
391 detail: "Deletes the character at the cursor position in the cell\nedit buffer.",
392 },
393 HelpEntry {
394 tags: &["Left-insert", "Right-insert"],
395 category: HelpCategory::Insert,
396 summary: "Move cursor within cell",
397 detail: "Arrow keys move the cursor left/right within the cell edit\nbuffer during Insert mode.",
398 },
399 HelpEntry {
400 tags: &["Home"],
401 category: HelpCategory::Insert,
402 summary: "Move to start of cell",
403 detail: "Move the cursor to the beginning of the cell edit buffer.",
404 },
405 HelpEntry {
406 tags: &["End"],
407 category: HelpCategory::Insert,
408 summary: "Move to end of cell",
409 detail: "Move the cursor to the end of the cell edit buffer.",
410 },
411];
412
413pub static VISUAL_ENTRIES: &[HelpEntry] = &[
414 HelpEntry {
415 tags: &["v-visual"],
416 category: HelpCategory::Visual,
417 summary: "Enter Visual mode",
418 detail: "Start visual selection from Normal mode. The anchor is set at\nthe current cursor position.",
419 },
420 HelpEntry {
421 tags: &["Ctrl+V-visual"],
422 category: HelpCategory::Visual,
423 summary: "Enter Visual Block mode",
424 detail: "Start rectangular block selection from Normal mode.",
425 },
426 HelpEntry {
427 tags: &["count-visual", "[count]-visual"],
428 category: HelpCategory::Visual,
429 summary: "Count prefix in Visual mode ([count]motion)",
430 detail: "Type digits before a motion key (h j k l) to extend the\n\
431 selection by that many cells. For example, v then 3l selects\n\
432 the current cell plus 3 more to the right; 5j extends the\n\
433 selection 5 rows down.",
434 },
435 HelpEntry {
436 tags: &["d-visual"],
437 category: HelpCategory::Visual,
438 summary: "Delete selection",
439 detail: "Clear all cells in the visual selection. The contents are\nstored in the register. Returns to Normal mode.",
440 },
441 HelpEntry {
442 tags: &["y-visual"],
443 category: HelpCategory::Visual,
444 summary: "Yank selection",
445 detail: "Copy all cells in the visual selection to the register.\nReturns to Normal mode.",
446 },
447 HelpEntry {
448 tags: &["Esc-visual"],
449 category: HelpCategory::Visual,
450 summary: "Cancel selection",
451 detail: "Exit Visual mode and return to Normal mode without\nmodifying any cells.",
452 },
453 HelpEntry {
454 tags: &["u-visual"],
455 category: HelpCategory::Visual,
456 summary: "Lowercase selection",
457 detail: "Convert every character in every selected cell to lowercase.\n\
458 Formula cells in the selection are skipped. Undoable with u\n\
459 after returning to Normal mode.",
460 },
461 HelpEntry {
462 tags: &["U-visual"],
463 category: HelpCategory::Visual,
464 summary: "Uppercase selection",
465 detail: "Convert every character in every selected cell to uppercase.\n\
466 Formula cells in the selection are skipped. Undoable with u\n\
467 after returning to Normal mode.",
468 },
469 HelpEntry {
470 tags: &["~-visual"],
471 category: HelpCategory::Visual,
472 summary: "Toggle case of selection",
473 detail: "Toggle the case of every character in every selected cell\n\
474 (uppercase ↔ lowercase). Formula cells in the selection are\n\
475 skipped. Undoable with u after returning to Normal mode.",
476 },
477];
478
479pub static COMMAND_ENTRIES: &[HelpEntry] = &[
480 HelpEntry {
481 tags: &[":w", ":write"],
482 category: HelpCategory::Command,
483 summary: "Save file",
484 detail: "Write the current sheet to disk. If no filename has been set,\nuse :w <path> to specify one.\n\nIf the sheet contains formulas and you save as CSV/TSV,\nCell will warn you. Use :w file.cell to preserve formulas,\nor :w! to force save as CSV (formulas become values).\n\nIf the active delimiter (see :set delimiter) does not match\nthe file extension convention, Cell will also warn you.\nUse :w! to override.",
485 },
486 HelpEntry {
487 tags: &[":w!"],
488 category: HelpCategory::Command,
489 summary: "Force save",
490 detail: "Write the current sheet to disk, bypassing both the\nformula-flatten warning and the non-standard-delimiter warning.",
491 },
492 HelpEntry {
493 tags: &[":q", ":quit"],
494 category: HelpCategory::Command,
495 summary: "Quit",
496 detail: "Exit Cell. Fails if there are unsaved changes.\nUse :q! to discard changes, or :wq to save and quit.",
497 },
498 HelpEntry {
499 tags: &[":q!"],
500 category: HelpCategory::Command,
501 summary: "Force quit",
502 detail: "Exit Cell without saving. All unsaved changes are discarded.",
503 },
504 HelpEntry {
505 tags: &[":wq"],
506 category: HelpCategory::Command,
507 summary: "Save and quit",
508 detail: "Write the current sheet to disk, then exit Cell.",
509 },
510 HelpEntry {
511 tags: &[":e", ":edit"],
512 category: HelpCategory::Command,
513 summary: "Open file",
514 detail: "Open a file for editing.\nUsage: :e <path>\n\nSupported formats: CSV, TSV, .cell (native format).",
515 },
516 HelpEntry {
517 tags: &[":sort"],
518 category: HelpCategory::Command,
519 summary: "Sort by column",
520 detail: "Sort all rows by the values in a column.\nUsage: :sort <column> [asc|desc]\n\nExamples:\n :sort A Sort by column A ascending\n :sort B desc Sort by column B descending",
521 },
522 HelpEntry {
523 tags: &[":set delimiter", "--delimiter", "delimiter"],
524 category: HelpCategory::Command,
525 summary: "Set the field delimiter",
526 detail: "Set the delimiter character used when reading or saving\nCSV/TSV files.\n\nUsage (ex-command): :set delimiter=|\n :set delimiter=;\nUsage (CLI flag): cell data.psv --delimiter '|'\n\nValid delimiters: any single printable ASCII character that\nis not a letter, digit, or double-quote (e.g. | ; , \\t).\n\nThe delimiter is auto-detected from file content on open\nwhen the --delimiter flag is not provided and the extension\nis not .tsv. Use --delimiter to override detection.\n\n:set delimiter only affects the next save — it does not\nre-parse the currently loaded file. To reload with a new\ndelimiter, close and reopen the file with --delimiter.",
527 },
528 HelpEntry {
529 tags: &[":help"],
530 category: HelpCategory::Command,
531 summary: "Open help",
532 detail: "Show this help screen.\nUsage: :help [topic]\n\n:help Show table of contents\n:help dd Show help for the dd command\n:help :w Show help for the :w command\n:help SUM Show help for the SUM formula",
533 },
534];
535
536pub static FORMULA_ENTRIES: &[HelpEntry] = &[
537 HelpEntry {
538 tags: &["SUM"],
539 category: HelpCategory::Formula,
540 summary: "Sum values in a range",
541 detail: "Returns the sum of all numeric values in the range.\nNon-numeric cells are ignored.\n\nUsage: =SUM(A1:A10)\n =SUM(B2:D5)",
542 },
543 HelpEntry {
544 tags: &["AVERAGE"],
545 category: HelpCategory::Formula,
546 summary: "Average of values in a range",
547 detail: "Returns the arithmetic mean of all numeric values in the range.\nNon-numeric cells are ignored. Returns #DIV/0! if no numeric\nvalues are found.\n\nUsage: =AVERAGE(A1:A10)",
548 },
549 HelpEntry {
550 tags: &["COUNT"],
551 category: HelpCategory::Formula,
552 summary: "Count numeric cells in a range",
553 detail: "Returns the number of cells containing numeric values in\nthe range. Non-numeric cells are not counted.\n\nUsage: =COUNT(A1:A10)",
554 },
555 HelpEntry {
556 tags: &["MIN"],
557 category: HelpCategory::Formula,
558 summary: "Minimum value in a range",
559 detail: "Returns the smallest numeric value in the range.\nNon-numeric cells are ignored. Returns 0 if no numeric\nvalues are found.\n\nUsage: =MIN(A1:A10)",
560 },
561 HelpEntry {
562 tags: &["MAX"],
563 category: HelpCategory::Formula,
564 summary: "Maximum value in a range",
565 detail: "Returns the largest numeric value in the range.\nNon-numeric cells are ignored. Returns 0 if no numeric\nvalues are found.\n\nUsage: =MAX(A1:A10)",
566 },
567 HelpEntry {
568 tags: &["IF"],
569 category: HelpCategory::Formula,
570 summary: "Conditional expression",
571 detail: "Returns one value if a condition is true, another if false.\n\nUsage: =IF(condition, value_if_true, value_if_false)\n\nExamples:\n =IF(A1>10, \"big\", \"small\")\n =IF(B2, C2, D2)",
572 },
573];