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: &["Ctrl+E"],
243 category: HelpCategory::Normal,
244 summary: "Scroll viewport down one row",
245 detail: "Scroll the viewport down one row without moving the cursor.\n\
246 If the cursor would scroll off the top, it stays pinned to\n\
247 the top visible row.",
248 },
249 HelpEntry {
250 tags: &["Ctrl+Y"],
251 category: HelpCategory::Normal,
252 summary: "Scroll viewport up one row",
253 detail: "Scroll the viewport up one row without moving the cursor.\n\
254 If the cursor would scroll off the bottom, it stays pinned\n\
255 to the bottom visible row.",
256 },
257 HelpEntry {
258 tags: &["zz"],
259 category: HelpCategory::Normal,
260 summary: "Recenter viewport on cursor",
261 detail: "Scroll the viewport so the cursor sits at the vertical\n\
262 center of the visible rows. Cursor position is unchanged.",
263 },
264 HelpEntry {
265 tags: &["zt"],
266 category: HelpCategory::Normal,
267 summary: "Scroll cursor to top of viewport",
268 detail: "Scroll the viewport so the cursor row becomes the top\n\
269 visible row. Cursor position is unchanged.",
270 },
271 HelpEntry {
272 tags: &["zb"],
273 category: HelpCategory::Normal,
274 summary: "Scroll cursor to bottom of viewport",
275 detail: "Scroll the viewport so the cursor row becomes the bottom\n\
276 visible row. Cursor position is unchanged.",
277 },
278 HelpEntry {
279 tags: &["H"],
280 category: HelpCategory::Normal,
281 summary: "Cursor to top of viewport",
282 detail: "Move the cursor to the topmost visible row, keeping the\n\
283 current column. Viewport is unchanged.",
284 },
285 HelpEntry {
286 tags: &["M"],
287 category: HelpCategory::Normal,
288 summary: "Cursor to middle of viewport",
289 detail: "Move the cursor to the middle visible row, keeping the\n\
290 current column. Viewport is unchanged.",
291 },
292 HelpEntry {
293 tags: &["L"],
294 category: HelpCategory::Normal,
295 summary: "Cursor to bottom of viewport",
296 detail: "Move the cursor to the bottommost visible row, keeping the\n\
297 current column. Viewport is unchanged.",
298 },
299 HelpEntry {
300 tags: &["m", "mark"],
301 category: HelpCategory::Normal,
302 summary: "Set mark (m{a-z})",
303 detail: "After pressing m, the next lowercase letter records the\n\
304 current cursor position as a named mark. Marks are\n\
305 session-only. Jump back with '{a-z} (line-wise) or\n\
306 `{a-z} (exact cell).",
307 },
308 HelpEntry {
309 tags: &["'"],
310 category: HelpCategory::Normal,
311 summary: "Jump to mark (line-wise)",
312 detail: "After pressing ', the next lowercase letter jumps the\n\
313 cursor to the row of the matching mark, at column A.\n\
314 If the mark is unset, status reports `E20: Mark not set`.",
315 },
316 HelpEntry {
317 tags: &["`", "backtick"],
318 category: HelpCategory::Normal,
319 summary: "Jump to mark (exact cell)",
320 detail: "After pressing `, the next lowercase letter jumps the\n\
321 cursor to the exact cell of the matching mark.\n\
322 If the mark is unset, status reports `E20: Mark not set`.",
323 },
324 HelpEntry {
325 tags: &["Ctrl+O"],
326 category: HelpCategory::Normal,
327 summary: "Jump back in jump list",
328 detail: "Move backward through the jump list, which records cursor\n\
329 positions across long-distance motions (gg, G, marks,\n\
330 search). Pairs with Ctrl+I / Tab to jump forward. The\n\
331 jump list is capped at 100 entries.",
332 },
333 HelpEntry {
334 tags: &["Ctrl+I", "Tab"],
335 category: HelpCategory::Normal,
336 summary: "Jump forward in jump list",
337 detail: "Move forward through the jump list. Pairs with Ctrl+O\n\
338 to jump back. Mid-stack jumps truncate the forward history.",
339 },
340 HelpEntry {
341 tags: &["{"],
342 category: HelpCategory::Normal,
343 summary: "Block jump up in column",
344 detail: "Jump to the previous block boundary in the current column,\n\
345 mirroring vim's paragraph motion. From a non-empty cell,\n\
346 lands on the first empty row above the current block;\n\
347 from an empty cell, lands on the next non-empty row above.",
348 },
349 HelpEntry {
350 tags: &["}"],
351 category: HelpCategory::Normal,
352 summary: "Block jump down in column",
353 detail: "Jump to the next block boundary in the current column,\n\
354 mirroring vim's paragraph motion. From a non-empty cell,\n\
355 lands on the first empty row below the current block;\n\
356 from an empty cell, lands on the next non-empty row below.",
357 },
358 HelpEntry {
359 tags: &["*"],
360 category: HelpCategory::Normal,
361 summary: "Search current cell value forward",
362 detail: "Treat the current cell's displayed value as the search\n\
363 pattern and jump to the next matching cell. The pattern\n\
364 is stored, so n / N continue stepping through matches.",
365 },
366 HelpEntry {
367 tags: &["#"],
368 category: HelpCategory::Normal,
369 summary: "Search current cell value backward",
370 detail: "Treat the current cell's displayed value as the search\n\
371 pattern and jump to the previous matching cell. The pattern\n\
372 is stored, so n / N continue stepping through matches.",
373 },
374 HelpEntry {
375 tags: &["gv"],
376 category: HelpCategory::Normal,
377 summary: "Re-enter previous visual selection",
378 detail: "Re-enter Visual mode with the same anchor, cursor, and\n\
379 visual kind (Character / Line / Block) as the last\n\
380 selection. No-op if no previous selection exists.",
381 },
382 HelpEntry {
383 tags: &["c"],
384 category: HelpCategory::Normal,
385 summary: "Change cell",
386 detail: "Clear the current cell and enter Insert mode to type its new\n\
387 content. Equivalent to x followed by i.",
388 },
389 HelpEntry {
390 tags: &["V"],
391 category: HelpCategory::Normal,
392 summary: "Enter Visual Line mode",
393 detail: "Start full-row (line-wise) visual selection from the\n\
394 current row. Use j/k to extend; press d/y/c to act on the\n\
395 selected rows.",
396 },
397 HelpEntry {
398 tags: &["i", "a"],
399 category: HelpCategory::Normal,
400 summary: "Enter Insert mode",
401 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.",
402 },
403 HelpEntry {
404 tags: &["o"],
405 category: HelpCategory::Normal,
406 summary: "Enter Insert mode (new line)",
407 detail: "Switch to Insert mode. In Cell, behaves the same as i\n(there are no multi-line cells).",
408 },
409 HelpEntry {
410 tags: &["Enter"],
411 category: HelpCategory::Normal,
412 summary: "Edit cell",
413 detail: "Enter Insert mode to edit the current cell. Same as i.",
414 },
415 HelpEntry {
416 tags: &["v"],
417 category: HelpCategory::Normal,
418 summary: "Enter Visual mode",
419 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.",
420 },
421 HelpEntry {
422 tags: &["Ctrl+V"],
423 category: HelpCategory::Normal,
424 summary: "Enter Visual Block mode",
425 detail: "Start block (rectangular) selection from the current cell.\nUse h/j/k/l to extend. Press d to delete or y to yank.",
426 },
427 HelpEntry {
428 tags: &["/"],
429 category: HelpCategory::Normal,
430 summary: "Search forward",
431 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.",
432 },
433 HelpEntry {
434 tags: &["?"],
435 category: HelpCategory::Normal,
436 summary: "Search backward",
437 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.",
438 },
439 HelpEntry {
440 tags: &["n"],
441 category: HelpCategory::Normal,
442 summary: "Next search match",
443 detail: "Jump to the next cell matching the last search pattern.",
444 },
445 HelpEntry {
446 tags: &["N"],
447 category: HelpCategory::Normal,
448 summary: "Previous search match",
449 detail: "Jump to the previous cell matching the last search pattern.",
450 },
451 HelpEntry {
452 tags: &["f"],
453 category: HelpCategory::Normal,
454 summary: "Find char in row (forward)",
455 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.",
456 },
457 HelpEntry {
458 tags: &["F"],
459 category: HelpCategory::Normal,
460 summary: "Find char in row (backward)",
461 detail: "Like f, but searches the current row to the left of the cursor.",
462 },
463 HelpEntry {
464 tags: &[";"],
465 category: HelpCategory::Normal,
466 summary: "Repeat last find",
467 detail: "Repeat the last f / F find in the same direction.",
468 },
469 HelpEntry {
470 tags: &[","],
471 category: HelpCategory::Normal,
472 summary: "Repeat last find reversed",
473 detail: "Repeat the last f / F find in the opposite direction.",
474 },
475 HelpEntry {
476 tags: &["~", "tilde"],
477 category: HelpCategory::Normal,
478 summary: "Toggle case of first character",
479 detail: "Toggle the case of the first character of the current cell's value\n\
480 and advance the cursor one column to the right (vim `~` semantics\n\
481 scoped to one cell). No-op on formula cells.",
482 },
483 HelpEntry {
484 tags: &["guu"],
485 category: HelpCategory::Normal,
486 summary: "Lowercase entire cell",
487 detail: "Convert every character in the current cell's value to lowercase.\n\
488 No-op on formula cells. Undoable with u.",
489 },
490 HelpEntry {
491 tags: &["gUU"],
492 category: HelpCategory::Normal,
493 summary: "Uppercase entire cell",
494 detail: "Convert every character in the current cell's value to uppercase.\n\
495 No-op on formula cells. Undoable with u.",
496 },
497 HelpEntry {
498 tags: &["g~~"],
499 category: HelpCategory::Normal,
500 summary: "Toggle case of entire cell",
501 detail: "Toggle the case of every character in the current cell's value\n\
502 (uppercase ↔ lowercase). No-op on formula cells. Undoable with u.",
503 },
504 HelpEntry {
505 tags: &["Ctrl+A"],
506 category: HelpCategory::Normal,
507 summary: "Increment number under cursor ([count]Ctrl+A)",
508 detail: "Add 1 (or [count]) to the number stored in the current cell.\n\
509 Dependent formula cells are re-evaluated automatically.\n\
510 No-op if the cell contains a formula (shows an error message)\n\
511 or non-numeric text. Repeatable with '.'.",
512 },
513 HelpEntry {
514 tags: &["Ctrl+X"],
515 category: HelpCategory::Normal,
516 summary: "Decrement number under cursor ([count]Ctrl+X)",
517 detail: "Subtract 1 (or [count]) from the number stored in the current cell.\n\
518 Dependent formula cells are re-evaluated automatically.\n\
519 No-op if the cell contains a formula (shows an error message)\n\
520 or non-numeric text. Repeatable with '.'.",
521 },
522];
523
524pub static INSERT_ENTRIES: &[HelpEntry] = &[
525 HelpEntry {
526 tags: &["Esc"],
527 category: HelpCategory::Insert,
528 summary: "Confirm edit, return to Normal",
529 detail: "Saves the current cell content and returns to Normal mode.",
530 },
531 HelpEntry {
532 tags: &["Enter-insert"],
533 category: HelpCategory::Insert,
534 summary: "Confirm edit and move down",
535 detail: "Saves the current cell content and returns to Normal mode.\nIn Insert mode, Enter confirms the edit (same as Esc).",
536 },
537 HelpEntry {
538 tags: &["Backspace"],
539 category: HelpCategory::Insert,
540 summary: "Delete character before cursor",
541 detail: "Deletes the character to the left of the cursor in the cell\nedit buffer.",
542 },
543 HelpEntry {
544 tags: &["Delete"],
545 category: HelpCategory::Insert,
546 summary: "Delete character at cursor",
547 detail: "Deletes the character at the cursor position in the cell\nedit buffer.",
548 },
549 HelpEntry {
550 tags: &["Left-insert", "Right-insert"],
551 category: HelpCategory::Insert,
552 summary: "Move cursor within cell",
553 detail: "Arrow keys move the cursor left/right within the cell edit\nbuffer during Insert mode.",
554 },
555 HelpEntry {
556 tags: &["Home"],
557 category: HelpCategory::Insert,
558 summary: "Move to start of cell",
559 detail: "Move the cursor to the beginning of the cell edit buffer.",
560 },
561 HelpEntry {
562 tags: &["End"],
563 category: HelpCategory::Insert,
564 summary: "Move to end of cell",
565 detail: "Move the cursor to the end of the cell edit buffer.",
566 },
567];
568
569pub static VISUAL_ENTRIES: &[HelpEntry] = &[
570 HelpEntry {
571 tags: &["v-visual"],
572 category: HelpCategory::Visual,
573 summary: "Enter Visual mode",
574 detail: "Start visual selection from Normal mode. The anchor is set at\nthe current cursor position.",
575 },
576 HelpEntry {
577 tags: &["Ctrl+V-visual"],
578 category: HelpCategory::Visual,
579 summary: "Enter Visual Block mode",
580 detail: "Start rectangular block selection from Normal mode.",
581 },
582 HelpEntry {
583 tags: &["count-visual", "[count]-visual"],
584 category: HelpCategory::Visual,
585 summary: "Count prefix in Visual mode ([count]motion)",
586 detail: "Type digits before a motion key (h j k l) to extend the\n\
587 selection by that many cells. For example, v then 3l selects\n\
588 the current cell plus 3 more to the right; 5j extends the\n\
589 selection 5 rows down.",
590 },
591 HelpEntry {
592 tags: &["d-visual"],
593 category: HelpCategory::Visual,
594 summary: "Delete selection",
595 detail: "Clear all cells in the visual selection. The contents are\nstored in the register. Returns to Normal mode.",
596 },
597 HelpEntry {
598 tags: &["y-visual"],
599 category: HelpCategory::Visual,
600 summary: "Yank selection",
601 detail: "Copy all cells in the visual selection to the register.\nReturns to Normal mode.",
602 },
603 HelpEntry {
604 tags: &["Esc-visual"],
605 category: HelpCategory::Visual,
606 summary: "Cancel selection",
607 detail: "Exit Visual mode and return to Normal mode without\nmodifying any cells.",
608 },
609 HelpEntry {
610 tags: &["u-visual"],
611 category: HelpCategory::Visual,
612 summary: "Lowercase selection",
613 detail: "Convert every character in every selected cell to lowercase.\n\
614 Formula cells in the selection are skipped. Undoable with u\n\
615 after returning to Normal mode.",
616 },
617 HelpEntry {
618 tags: &["U-visual"],
619 category: HelpCategory::Visual,
620 summary: "Uppercase selection",
621 detail: "Convert every character in every selected cell to uppercase.\n\
622 Formula cells in the selection are skipped. Undoable with u\n\
623 after returning to Normal mode.",
624 },
625 HelpEntry {
626 tags: &["~-visual"],
627 category: HelpCategory::Visual,
628 summary: "Toggle case of selection",
629 detail: "Toggle the case of every character in every selected cell\n\
630 (uppercase ↔ lowercase). Formula cells in the selection are\n\
631 skipped. Undoable with u after returning to Normal mode.",
632 },
633];
634
635pub static COMMAND_ENTRIES: &[HelpEntry] = &[
636 HelpEntry {
637 tags: &[":w", ":write"],
638 category: HelpCategory::Command,
639 summary: "Save file",
640 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.",
641 },
642 HelpEntry {
643 tags: &[":w!"],
644 category: HelpCategory::Command,
645 summary: "Force save",
646 detail: "Write the current sheet to disk, bypassing both the\nformula-flatten warning and the non-standard-delimiter warning.",
647 },
648 HelpEntry {
649 tags: &[":q", ":quit"],
650 category: HelpCategory::Command,
651 summary: "Quit",
652 detail: "Exit Cell. Fails if there are unsaved changes.\nUse :q! to discard changes, or :wq to save and quit.",
653 },
654 HelpEntry {
655 tags: &[":q!"],
656 category: HelpCategory::Command,
657 summary: "Force quit",
658 detail: "Exit Cell without saving. All unsaved changes are discarded.",
659 },
660 HelpEntry {
661 tags: &[":wq"],
662 category: HelpCategory::Command,
663 summary: "Save and quit",
664 detail: "Write the current sheet to disk, then exit Cell.",
665 },
666 HelpEntry {
667 tags: &[":e", ":edit"],
668 category: HelpCategory::Command,
669 summary: "Open file",
670 detail: "Open a file for editing.\nUsage: :e <path>\n\nSupported formats: CSV, TSV, .cell (native format).",
671 },
672 HelpEntry {
673 tags: &[":sort"],
674 category: HelpCategory::Command,
675 summary: "Sort by column",
676 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",
677 },
678 HelpEntry {
679 tags: &[":set delimiter", "--delimiter", "delimiter"],
680 category: HelpCategory::Command,
681 summary: "Set the field delimiter",
682 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.",
683 },
684 HelpEntry {
685 tags: &[":help"],
686 category: HelpCategory::Command,
687 summary: "Open help",
688 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",
689 },
690];
691
692pub static FORMULA_ENTRIES: &[HelpEntry] = &[
693 HelpEntry {
694 tags: &["SUM"],
695 category: HelpCategory::Formula,
696 summary: "Sum values in a range",
697 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)",
698 },
699 HelpEntry {
700 tags: &["AVERAGE"],
701 category: HelpCategory::Formula,
702 summary: "Average of values in a range",
703 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)",
704 },
705 HelpEntry {
706 tags: &["COUNT"],
707 category: HelpCategory::Formula,
708 summary: "Count numeric cells in a range",
709 detail: "Returns the number of cells containing numeric values in\nthe range. Non-numeric cells are not counted.\n\nUsage: =COUNT(A1:A10)",
710 },
711 HelpEntry {
712 tags: &["MIN"],
713 category: HelpCategory::Formula,
714 summary: "Minimum value in a range",
715 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)",
716 },
717 HelpEntry {
718 tags: &["MAX"],
719 category: HelpCategory::Formula,
720 summary: "Maximum value in a range",
721 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)",
722 },
723 HelpEntry {
724 tags: &["IF"],
725 category: HelpCategory::Formula,
726 summary: "Conditional expression",
727 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)",
728 },
729];
730
731pub static MOUSE_ENTRIES: &[HelpEntry] = &[
732 HelpEntry {
733 tags: &["mouse", ":set mouse"],
734 category: HelpCategory::Mouse,
735 summary: "Enable / disable mouse support",
736 detail: "Mouse support is OFF by default. Toggle at runtime:\n\
737 \n\
738 :set mouse on Enable mouse capture.\n\
739 :set mouse off Disable mouse capture.\n\
740 :set mouse toggle Flip the current state.\n\
741 \n\
742 When mouse mode is on, the terminal stops doing native\n\
743 text selection. Hold your terminal's bypass modifier to\n\
744 fall back to native selection for copy:\n\
745 \n\
746 - Linux & Windows Terminal: Shift\n\
747 - macOS Terminal.app and iTerm2: Option/Alt\n\
748 - tmux/screen: see your terminal's docs",
749 },
750 HelpEntry {
751 tags: &["mouse-click", "click"],
752 category: HelpCategory::Mouse,
753 summary: "Left-click moves the cursor",
754 detail: "Left-click on a grid cell moves the cursor there. From\n\
755 Insert mode the in-progress edit is committed first;\n\
756 from Command mode the prompt is cancelled; from Visual\n\
757 the selection is exited.\n\
758 \n\
759 Click on the formula bar, status bar, or padding around\n\
760 the grid is a no-op and never commits an edit.",
761 },
762 HelpEntry {
763 tags: &["mouse-drag", "drag"],
764 category: HelpCategory::Mouse,
765 summary: "Click + drag selects a range",
766 detail: "Drag inside the grid: enters Visual mode and extends the\n\
767 selection from the click cell to the current cell.\n\
768 \n\
769 Drag on a column header: selects whole columns.\n\
770 Drag on a row header: selects whole rows.\n\
771 \n\
772 Dragging a cell selection past the visible edge auto-\n\
773 scrolls the viewport one row/column per drag event.",
774 },
775 HelpEntry {
776 tags: &["mouse-scroll", "scroll-wheel", "wheel"],
777 category: HelpCategory::Mouse,
778 summary: "Scroll wheel scrolls the viewport",
779 detail: "The scroll wheel scrolls the viewport up or down by 3\n\
780 rows. The cursor does not move, even if it scrolls out\n\
781 of view (matches Vim's mouse behaviour).\n\
782 \n\
783 Horizontal scroll (Shift+wheel on most terminals)\n\
784 scrolls the viewport left or right when the terminal\n\
785 emits ScrollLeft / ScrollRight events.",
786 },
787 HelpEntry {
788 tags: &["mouse-double-click", "double-click", "edit-cell"],
789 category: HelpCategory::Mouse,
790 summary: "Double-click enters Insert mode",
791 detail: "Two left-clicks on the same cell within ~400ms enter\n\
792 Insert mode on that cell. A second click on a different\n\
793 cell, or after the threshold, is treated as a fresh\n\
794 single click.",
795 },
796 HelpEntry {
797 tags: &["mouse-bypass", "shift-click"],
798 category: HelpCategory::Mouse,
799 summary: "Shift+click bypasses mouse capture",
800 detail: "Holding Shift while clicking is treated as a no-op by\n\
801 cell, allowing the terminal's native text selection to\n\
802 take over. Use this to copy a cell value or formula\n\
803 string out to your system clipboard. (On macOS\n\
804 Terminal.app and iTerm2 the bypass modifier is\n\
805 typically Option/Alt — check your terminal settings.)",
806 },
807];