1#[derive(Clone, Copy)]
27pub enum Handler {
28 Leaf(fn(&mut crate::editor::Editor, char)),
31 Alias(&'static str),
33 Motion,
36 Operator,
38 ObjectPrefix,
42 Prefix,
44 TextLine,
47 AbsorbChar(AbsorbKind),
49 AbsorbRegister,
51 Soon,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum AbsorbKind {
58 Replace,
59 MarkSet,
60 MarkJump,
61 Find,
62 MacroRecord,
64 MacroPlay,
66}
67
68pub struct Binding {
72 pub keys: &'static str,
73 pub desc: &'static str,
74 pub section: &'static str,
76 pub live: bool,
78 pub id: &'static str,
80 pub handler: Handler,
81}
82
83pub const SECTIONS: &[&str] = &["normal", "visual", "insert", "leader", "git", "ex+panes"];
84
85pub const BINDINGS: &[Binding] = &[
86 Binding {
88 keys: "h j k l",
89 desc: "move (never off the line)",
90 section: "normal",
91 live: true,
92 id: "move",
93 handler: Handler::Motion,
94 },
95 Binding {
96 keys: "w b e W B E",
97 desc: "word / WORD motions",
98 section: "normal",
99 live: true,
100 id: "word-motions",
101 handler: Handler::Motion,
102 },
103 Binding {
104 keys: "zz zt zb",
105 desc: "center/top/bottom the cursor line",
106 section: "normal",
107 live: true,
108 id: "view-place",
109 handler: Handler::Leaf(|e, k| e.view_place(k)),
110 },
111 Binding {
112 keys: "H M L",
113 desc: "top/middle/bottom visible line",
114 section: "normal",
115 live: true,
116 id: "visible-jumps",
117 handler: Handler::Leaf(|e, k| e.jump_visible(k, 1)),
118 },
119 Binding {
120 keys: "ZZ",
121 desc: "write + close window",
122 section: "normal",
123 live: true,
124 id: "write-quit",
125 handler: Handler::Leaf(|e, _| e.write_quit()),
126 },
127 Binding {
128 keys: "gv",
129 desc: "reselect last visual",
130 section: "normal",
131 live: true,
132 id: "reselect-visual",
133 handler: Handler::Leaf(|e, _| e.reselect_visual()),
134 },
135 Binding {
136 keys: "gi",
137 desc: "insert at last insert",
138 section: "normal",
139 live: true,
140 id: "insert-at-last",
141 handler: Handler::Leaf(|e, _| e.insert_at_last()),
142 },
143 Binding {
144 keys: "g;",
145 desc: "older change (changelist)",
146 section: "normal",
147 live: true,
148 id: "change-back",
149 handler: Handler::Leaf(|e, _| e.change_jump(true)),
150 },
151 Binding {
152 keys: "g,",
153 desc: "newer change (changelist)",
154 section: "normal",
155 live: true,
156 id: "change-forward",
157 handler: Handler::Leaf(|e, _| e.change_jump(false)),
158 },
159 Binding {
160 keys: "ge gE { }",
161 desc: "word-end back / paragraph motions",
162 section: "normal",
163 live: true,
164 id: "paragraph-motions",
165 handler: Handler::Motion,
166 },
167 Binding {
168 keys: "0 $ G %",
169 desc: "line/file/pair jumps",
170 section: "normal",
171 live: true,
172 id: "line-jumps",
173 handler: Handler::Motion,
174 },
175 Binding {
176 keys: "g<space>",
177 desc: "collection: open full source at caret",
178 section: "normal",
179 live: true,
180 id: "collection-source",
181 handler: Handler::Leaf(|e, _| e.collection_open_source_pub()),
182 },
183 Binding {
184 keys: "gb",
185 desc: "select next occurrence of word/selection",
186 section: "normal",
187 live: true,
188 id: "occurrence-next",
189 handler: Handler::Leaf(|e, _| e.occurrence_next_pub()),
190 },
191 Binding {
192 keys: "gB",
193 desc: "select all occurrences in buffer",
194 section: "normal",
195 live: true,
196 id: "occurrence-all",
197 handler: Handler::Leaf(|e, _| e.occurrence_all_pub()),
198 },
199 Binding {
200 keys: "gg",
201 desc: "top of file",
202 section: "normal",
203 live: true,
204 id: "top",
205 handler: Handler::Motion,
206 },
207 Binding {
208 keys: "enter",
209 desc: "line down, first non-blank (blame gutter: dive)",
210 section: "normal",
211 live: true,
212 id: "enter",
213 handler: Handler::Leaf(|e, _| e.enter_pub()),
214 },
215 Binding {
216 keys: "tab",
217 desc: "jump list forward (ctrl-i)",
218 section: "normal",
219 live: true,
220 id: "jump-forward",
221 handler: Handler::Leaf(|e, _| e.jump_forward()),
222 },
223 Binding {
224 keys: "ctrl-r",
225 desc: "redo",
226 section: "normal",
227 live: true,
228 id: "redo",
229 handler: Handler::Leaf(|e, _| e.redo()),
230 },
231 Binding {
232 keys: "ctrl-d ctrl-u ctrl-f ctrl-b",
233 desc: "half/full page scroll (count = lines)",
234 section: "normal",
235 live: true,
236 id: "scroll-pages",
237 handler: Handler::Leaf(|_, _| {}), },
239 Binding {
240 keys: "ctrl-^",
241 desc: "alternate buffer",
242 section: "normal",
243 live: true,
244 id: "alternate-buffer",
245 handler: Handler::Leaf(|e, _| e.alternate_buffer()),
246 },
247 Binding {
248 keys: "q<a>",
249 desc: "record macro into register",
250 section: "normal",
251 live: true,
252 id: "macro-record",
253 handler: Handler::AbsorbChar(AbsorbKind::MacroRecord),
254 },
255 Binding {
256 keys: "@<a>",
257 desc: "play macro (count repeats)",
258 section: "normal",
259 live: true,
260 id: "macro-play",
261 handler: Handler::AbsorbChar(AbsorbKind::MacroPlay),
262 },
263 Binding {
264 keys: "gr",
265 desc: "references (LSP)",
266 section: "normal",
267 live: true,
268 id: "references",
269 handler: Handler::Leaf(|e, _| e.lsp_locations_pub(strop_lsp::LocKind::References)),
270 },
271 Binding {
272 keys: "gI",
273 desc: "implementation (LSP)",
274 section: "normal",
275 live: true,
276 id: "implementation",
277 handler: Handler::Leaf(|e, _| e.lsp_locations_pub(strop_lsp::LocKind::Implementation)),
278 },
279 Binding {
280 keys: "gy",
281 desc: "type definition (LSP)",
282 section: "normal",
283 live: true,
284 id: "type-definition",
285 handler: Handler::Leaf(|e, _| e.lsp_locations_pub(strop_lsp::LocKind::TypeDefinition)),
286 },
287 Binding {
288 keys: "gD",
289 desc: "declaration (LSP)",
290 section: "normal",
291 live: true,
292 id: "declaration",
293 handler: Handler::Leaf(|e, _| e.lsp_locations_pub(strop_lsp::LocKind::Declaration)),
294 },
295 Binding {
296 keys: "]d [d",
297 desc: "next/prev diagnostic",
298 section: "normal",
299 live: true,
300 id: "diagnostic-jumps",
301 handler: Handler::Leaf(|e, k| e.jump_diagnostic_pub(k != '[')),
302 },
303 Binding {
304 keys: "gd",
305 desc: "goto definition (LSP)",
306 section: "normal",
307 live: true,
308 id: "goto-definition",
309 handler: Handler::Leaf(|e, _| crate::editor::Editor::lsp_goto_definition_pub(e)),
310 },
311 Binding {
312 keys: "gs",
313 desc: "switch source/header (clangd)",
314 section: "normal",
315 live: true,
316 id: "switch-source-header",
317 handler: Handler::Leaf(|e, _| crate::editor::Editor::lsp_switch_source_header_pub(e)),
318 },
319 Binding {
320 keys: "f<c> F<c> t<c> T<c>",
321 desc: "find/till char (candidates light up)",
322 section: "normal",
323 live: true,
324 id: "find-char",
325 handler: Handler::AbsorbChar(AbsorbKind::Find),
326 },
327 Binding {
328 keys: ":",
329 desc: "ex command line",
330 section: "normal",
331 live: true,
332 id: "ex-line",
333 handler: Handler::TextLine,
334 },
335 Binding {
336 keys: "/ ?",
337 desc: "literal search forward / backward (live as you type or delete)",
338 section: "normal",
339 live: true,
340 id: "search",
341 handler: Handler::TextLine,
342 },
343 Binding {
344 keys: "n",
345 desc: "next match",
346 section: "normal",
347 live: true,
348 id: "search-next",
349 handler: Handler::Leaf(|e, _| e.repeat_search_pub(false)),
350 },
351 Binding {
352 keys: "N",
353 desc: "previous match",
354 section: "normal",
355 live: true,
356 id: "search-prev",
357 handler: Handler::Leaf(|e, _| e.repeat_search_pub(true)),
358 },
359 Binding {
360 keys: "]c [c",
361 desc: "next / prev git hunk",
362 section: "normal",
363 live: true,
364 id: "hunk-nav",
365 handler: Handler::Leaf(|e, k| e.jump_hunk_pub(k != '[')),
366 },
367 Binding {
368 keys: "m<a>",
369 desc: "set mark at cursor",
370 section: "normal",
371 live: true,
372 id: "mark-set",
373 handler: Handler::AbsorbChar(AbsorbKind::MarkSet),
374 },
375 Binding {
376 keys: "'<a> `<a>",
377 desc: "jump to mark",
378 section: "normal",
379 live: true,
380 id: "mark-jump",
381 handler: Handler::AbsorbChar(AbsorbKind::MarkJump),
382 },
383 Binding {
384 keys: "* #",
385 desc: "word under cursor, forward / backward",
386 section: "normal",
387 live: true,
388 id: "word-search",
389 handler: Handler::Leaf(|e, k| e.search_word_under_cursor_pub(k == '#')),
390 },
391 Binding {
392 keys: "; ,",
393 desc: "repeat find, same / reversed",
394 section: "normal",
395 live: true,
396 id: "find-repeat",
397 handler: Handler::Leaf(|e, k| e.repeat_find_pub(k == ',')),
398 },
399 Binding {
400 keys: "|",
401 desc: "column motion (vim); pipe moved to space |",
402 section: "normal",
403 live: true,
404 id: "column-motion",
405 handler: Handler::Motion,
406 },
407 Binding {
408 keys: "space |",
409 desc: "pipe line/selection through shell (:! runs)",
410 section: "leader",
411 live: true,
412 id: "pipe-shell",
413 handler: Handler::TextLine,
414 },
415 Binding {
416 keys: "Q",
417 desc: "toggle cursor at point (multicursor)",
418 section: "normal",
419 live: true,
420 id: "cursor-toggle",
421 handler: Handler::Leaf(|e, _| crate::editor::Editor::toggle_cursor(e)),
422 },
423 Binding {
425 keys: "d y c > <",
426 desc: "operators + motion/object (live preview)",
427 section: "normal",
428 live: true,
429 id: "operators",
430 handler: Handler::Operator,
431 },
432 Binding {
433 keys: "dd yy cc",
434 desc: "line delete/yank/change",
435 section: "normal",
436 live: true,
437 id: "line-ops",
438 handler: Handler::Operator,
439 },
440 Binding {
441 keys: "D",
442 desc: "delete to line end",
443 section: "normal",
444 live: true,
445 id: "op-alias-d",
446 handler: Handler::Alias("d$"),
447 },
448 Binding {
449 keys: "C",
450 desc: "change to line end",
451 section: "normal",
452 live: true,
453 id: "op-alias-c",
454 handler: Handler::Alias("c$"),
455 },
456 Binding {
457 keys: "Y",
458 desc: "yank line",
459 section: "normal",
460 live: true,
461 id: "op-alias-y",
462 handler: Handler::Alias("yy"),
463 },
464 Binding {
465 keys: "s",
466 desc: "substitute char",
467 section: "normal",
468 live: true,
469 id: "op-alias-s",
470 handler: Handler::Alias("cl"),
471 },
472 Binding {
473 keys: "x X",
474 desc: "delete char / char back",
475 section: "normal",
476 live: true,
477 id: "char-delete",
478 handler: Handler::Leaf(|e, _| crate::editor::Editor::delete_char(e)),
479 },
480 Binding {
481 keys: "iw i\" i' i( i[ i{",
482 desc: "inner objects (quotes scan the line)",
483 section: "normal",
484 live: true,
485 id: "objects",
486 handler: Handler::ObjectPrefix,
487 },
488 Binding {
489 keys: "ds\" cs\"' ysiw\"",
490 desc: "surround: delete / change / add",
491 section: "normal",
492 live: true,
493 id: "surround",
494 handler: Handler::ObjectPrefix,
495 },
496 Binding {
497 keys: "i a A o O I",
498 desc: "insert (auto-indent)",
499 section: "normal",
500 live: true,
501 id: "insert-entries",
502 handler: Handler::Leaf(crate::editor::Editor::insert_entry_pub),
503 },
504 Binding {
505 keys: "p P",
506 desc: "paste after / before",
507 section: "normal",
508 live: true,
509 id: "paste",
510 handler: Handler::Leaf(|e, k| e.paste_named_pub(None, 1, k == 'P')),
511 },
512 Binding {
513 keys: "r<c>",
514 desc: "replace char",
515 section: "normal",
516 live: true,
517 id: "replace-char",
518 handler: Handler::AbsorbChar(AbsorbKind::Replace),
519 },
520 Binding {
521 keys: "J .",
522 desc: "join lines · repeat change",
523 section: "normal",
524 live: true,
525 id: "join-repeat",
526 handler: Handler::Leaf(crate::editor::Editor::join_or_repeat),
527 },
528 Binding {
529 keys: "^",
530 desc: "first non-blank",
531 section: "normal",
532 live: true,
533 id: "first-non-blank",
534 handler: Handler::Motion,
535 },
536 Binding {
537 keys: "~",
538 desc: "toggle case",
539 section: "normal",
540 live: true,
541 id: "toggle-case",
542 handler: Handler::Leaf(|e, _| crate::editor::Editor::toggle_case_pub(e)),
543 },
544 Binding {
545 keys: "S",
546 desc: "change line",
547 section: "normal",
548 live: true,
549 id: "subst-line",
550 handler: Handler::Alias("cc"),
551 },
552 Binding {
553 keys: "u ctrl-r",
554 desc: "undo / redo (one unit per command)",
555 section: "normal",
556 live: true,
557 id: "undo-redo",
558 handler: Handler::Leaf(|e, _| crate::editor::Editor::undo(e)),
559 },
560 Binding {
561 keys: "\"+y \"+p \"+P",
562 desc: "system clipboard: yank / paste after / before",
563 section: "normal",
564 live: true,
565 id: "reg-clipboard",
566 handler: Handler::AbsorbRegister,
567 },
568 Binding {
569 keys: "\"xy \"xp",
570 desc: "named register: yank / paste",
571 section: "normal",
572 live: true,
573 id: "reg-named",
574 handler: Handler::AbsorbRegister,
575 },
576 Binding {
577 keys: "ctrl-v",
578 desc: "visual block",
579 section: "normal",
580 live: true,
581 id: "visual-block",
582 handler: Handler::Leaf(|e, _| e.enter_block_pub()),
583 },
584 Binding {
585 keys: "v V",
586 desc: "visual / visual-line",
587 section: "normal",
588 live: true,
589 id: "visual-enter",
590 handler: Handler::Leaf(|e, k| e.enter_visual_pub(k)),
591 },
592 Binding {
594 keys: "d y c x > <",
595 desc: "operate on selection",
596 section: "visual",
597 live: true,
598 id: "visual-ops",
599 handler: Handler::Operator,
600 },
601 Binding {
602 keys: "S<c>",
603 desc: "wrap selection in pair",
604 section: "visual",
605 live: true,
606 id: "visual-surround",
607 handler: Handler::AbsorbChar(AbsorbKind::Replace),
608 },
609 Binding {
610 keys: "i<a> a<a>",
611 desc: "objects select (vi[ works)",
612 section: "visual",
613 live: true,
614 id: "visual-objects",
615 handler: Handler::ObjectPrefix,
616 },
617 Binding {
618 keys: "space y",
619 desc: "yank selection → clipboard",
620 section: "visual",
621 live: true,
622 id: "clip-yank",
623 handler: Handler::Leaf(|e, _| e.clipboard_yank_pub()),
624 },
625 Binding {
627 keys: "esc",
628 desc: "normal mode (session = one undo unit)",
629 section: "insert",
630 live: true,
631 id: "insert-esc",
632 handler: Handler::Prefix,
633 },
634 Binding {
635 keys: "backspace",
636 desc: "delete back",
637 section: "insert",
638 live: true,
639 id: "insert-bs",
640 handler: Handler::Prefix,
641 },
642 Binding {
643 keys: "enter",
644 desc: "new line (auto-indent)",
645 section: "insert",
646 live: true,
647 id: "insert-enter",
648 handler: Handler::Prefix,
649 },
650 Binding {
651 keys: "} ] )",
652 desc: "closer on indent-only line dedents",
653 section: "insert",
654 live: true,
655 id: "insert-closers",
656 handler: Handler::Prefix,
657 },
658 Binding {
660 keys: "space f",
661 desc: "file finder",
662 section: "leader",
663 live: true,
664 id: "files",
665 handler: Handler::Leaf(|e, _| e.open_picker(strop_picker::Kind::Files)),
666 },
667 Binding {
668 keys: "space o",
669 desc: "open remote destination",
670 section: "leader",
671 live: true,
672 id: "remote-open",
673 handler: Handler::Leaf(|e, _| e.open_remote_picker()),
674 },
675 Binding {
676 keys: "space b",
677 desc: "buffers (MRU)",
678 section: "leader",
679 live: true,
680 id: "buffers",
681 handler: Handler::Leaf(|e, _| e.open_picker(strop_picker::Kind::Buffers)),
682 },
683 Binding {
684 keys: "space /",
685 desc: "live grep",
686 section: "leader",
687 live: true,
688 id: "grep",
689 handler: Handler::Leaf(|e, _| e.open_picker(strop_picker::Kind::Grep)),
690 },
691 Binding {
692 keys: "space R",
693 desc: "global search & replace",
694 section: "leader",
695 live: true,
696 id: "replace-global",
697 handler: Handler::Leaf(|e, _| e.open_picker(strop_picker::Kind::Replace)),
698 },
699 Binding {
700 keys: "space ?",
701 desc: "this popup",
702 section: "leader",
703 live: true,
704 id: "help",
705 handler: Handler::Leaf(|e, _| crate::editor::Editor::open_help(e)),
706 },
707 Binding {
708 keys: "space y",
709 desc: "yank motion → system clipboard",
710 section: "leader",
711 live: true,
712 id: "clip-yank",
713 handler: Handler::Leaf(|e, _| e.clipboard_yank_pub()),
714 },
715 Binding {
716 keys: "space p",
717 desc: "paste clipboard after",
718 section: "leader",
719 live: true,
720 id: "clip-paste",
721 handler: Handler::Leaf(|e, k| e.clipboard_paste_pub(k == 'P')),
722 },
723 Binding {
724 keys: "space P",
725 desc: "paste clipboard before",
726 section: "leader",
727 live: true,
728 id: "clip-paste-before",
729 handler: Handler::Leaf(|e, k| e.clipboard_paste_pub(k == 'P')),
730 },
731 Binding {
732 keys: "space d",
733 desc: "diagnostics picker",
734 section: "leader",
735 live: true,
736 id: "diagnostics",
737 handler: Handler::Leaf(|e, _| e.open_diagnostics_picker()),
738 },
739 Binding {
740 keys: "space k",
741 desc: "hover docs",
742 section: "leader",
743 live: true,
744 id: "hover",
745 handler: Handler::Leaf(|e, _| e.lsp_hover_pub()),
746 },
747 Binding {
748 keys: "space a",
749 desc: "code actions",
750 section: "leader",
751 live: true,
752 id: "code-actions",
753 handler: Handler::Leaf(|e, _| e.lsp_code_actions_pub()),
754 },
755 Binding {
756 keys: "space s",
757 desc: "document symbols picker",
758 section: "leader",
759 live: true,
760 id: "document-symbols",
761 handler: Handler::Leaf(|e, _| e.lsp_document_symbols_pub()),
762 },
763 Binding {
764 keys: "space S",
765 desc: "workspace symbols picker",
766 section: "leader",
767 live: false,
768 id: "workspace-symbols",
769 handler: Handler::Soon,
770 },
771 Binding {
772 keys: "space j",
773 desc: "jumplist picker",
774 section: "leader",
775 live: true,
776 id: "jumplist-picker",
777 handler: Handler::Leaf(|e, _| e.open_picker(strop_picker::Kind::Jumps)),
778 },
779 Binding {
780 keys: "space u",
781 desc: "undo-tree browser",
782 section: "leader",
783 live: true,
784 id: "undo-tree",
785 handler: Handler::Leaf(|e, _| crate::editor::Editor::open_undo_tree(e)),
786 },
787 Binding {
788 keys: "space c",
789 desc: "cursor on next line too (multicursor)",
790 section: "leader",
791 live: true,
792 id: "cursor-stack",
793 handler: Handler::Leaf(|e, _| crate::editor::Editor::add_cursor_next_line(e)),
794 },
795 Binding {
797 keys: "space g",
798 desc: "git…",
799 section: "git",
800 live: true,
801 id: "git-prefix",
802 handler: Handler::Prefix,
803 },
804 Binding {
805 keys: "space g l",
806 desc: "commit browser",
807 section: "git",
808 live: true,
809 id: "git-log",
810 handler: Handler::Leaf(|e, _| e.open_log_pub(false)),
811 },
812 Binding {
813 keys: "space g h",
814 desc: "file history (visual: selected lines)",
815 section: "git",
816 live: true,
817 id: "git-file-history",
818 handler: Handler::Leaf(|e, _| e.open_log_pub(true)),
819 },
820 Binding {
821 keys: "space g b",
822 desc: "toggle blame gutter / card",
823 section: "git",
824 live: true,
825 id: "git-blame",
826 handler: Handler::Leaf(|e, _| e.toggle_blame_gutter()),
827 },
828 Binding {
829 keys: "space g y",
830 desc: "permalink: copy",
831 section: "git",
832 live: true,
833 id: "git-permalink-yank",
834 handler: Handler::Leaf(|e, _| e.yank_permalink()),
835 },
836 Binding {
837 keys: "space g o",
838 desc: "permalink: open",
839 section: "git",
840 live: true,
841 id: "git-permalink-open",
842 handler: Handler::Leaf(|e, _| e.open_permalink()),
843 },
844 Binding {
845 keys: "space g u",
846 desc: "hunk: undo unstaged (restore from index)",
847 section: "git",
848 live: true,
849 id: "git-hunk-undo",
850 handler: Handler::Leaf(|e, _| e.undo_hunk()),
851 },
852 Binding {
853 keys: "space g s",
854 desc: "hunk: stage (live→index)",
855 section: "git",
856 live: true,
857 id: "git-hunk-stage",
858 handler: Handler::Leaf(|e, _| e.stage_hunk()),
859 },
860 Binding {
861 keys: "space g S",
862 desc: "hunk: unstage (index→HEAD)",
863 section: "git",
864 live: true,
865 id: "git-hunk-unstage",
866 handler: Handler::Leaf(|e, _| e.unstage_hunk()),
867 },
868 Binding {
869 keys: "space g p",
870 desc: "hunk: preview",
871 section: "git",
872 live: true,
873 id: "git-hunk-preview",
874 handler: Handler::Leaf(|e, _| e.preview_hunk()),
875 },
876 Binding {
877 keys: "]f [f",
878 desc: "next / prev file in commit diff",
879 section: "git",
880 live: true,
881 id: "commit-file-nav",
882 handler: Handler::Soon,
883 },
884 Binding {
885 keys: "enter",
886 desc: "dive into the line's commit (blame gutter)",
887 section: "git",
888 live: true,
889 id: "surface-dive",
890 handler: Handler::Prefix,
891 },
892 Binding {
893 keys: "q",
894 desc: "close surface (readonly buffers)",
895 section: "git",
896 live: true,
897 id: "surface-close",
898 handler: Handler::Prefix,
899 },
900 Binding {
902 keys: ":w :q :q! :wq :w {file} :trust",
903 desc: "write / quit (force) / write-quit / write-as",
904 section: "ex+panes",
905 live: true,
906 id: "ex-write-quit",
907 handler: Handler::TextLine,
908 },
909 Binding {
910 keys: ":[range]s/a/b/[g] :N :% :N,Md :N,My",
911 desc: "substitute (literal) / goto line / ranged delete+yank",
912 section: "ex+panes",
913 live: true,
914 id: "ex-ranges",
915 handler: Handler::TextLine,
916 },
917 Binding {
918 keys: "ctrl-d ctrl-u ctrl-f ctrl-b",
919 desc: "half/full page scroll (count = lines)",
920 section: "ex+panes",
921 live: true,
922 id: "scroll-pages",
923 handler: Handler::TextLine,
924 },
925 Binding {
926 keys: ":e",
927 desc: "edit file",
928 section: "ex+panes",
929 live: true,
930 id: "ex-edit",
931 handler: Handler::TextLine,
932 },
933 Binding {
934 keys: ":help",
935 desc: "help buffer (this text — / searches it)",
936 section: "ex+panes",
937 live: true,
938 id: "ex-help",
939 handler: Handler::TextLine,
940 },
941 Binding {
942 keys: ":vs :sp",
943 desc: "split vertical / horizontal",
944 section: "ex+panes",
945 live: true,
946 id: "ex-split",
947 handler: Handler::TextLine,
948 },
949 Binding {
950 keys: "ctrl-w h / l / j / k / w",
951 desc: "pane move / cycle",
952 section: "ex+panes",
953 live: true,
954 id: "pane-nav",
955 handler: Handler::Leaf(crate::editor::Editor::pane_move_pub),
956 },
957 Binding {
958 keys: "ctrl-o / ctrl-i (tab)",
959 desc: "jump back / forward (jumplist)",
960 section: "ex+panes",
961 live: true,
962 id: "jumplist",
963 handler: Handler::Leaf(|e, _| crate::editor::Editor::jump_back(e)),
964 },
965 Binding {
966 keys: "ctrl-w v / s",
967 desc: "pane split (vs / sp)",
968 section: "ex+panes",
969 live: true,
970 id: "pane-split",
971 handler: Handler::Leaf(crate::editor::Editor::split_pub),
972 },
973 Binding {
974 keys: ":view :set",
975 desc: "readonly browsing (:set ro/noro; CLI: -R)",
976 section: "ex+panes",
977 live: true,
978 id: "readonly",
979 handler: Handler::TextLine,
980 },
981 Binding {
982 keys: "ctrl-w q",
983 desc: "close pane (last → buffer)",
984 section: "ex+panes",
985 live: true,
986 id: "pane-close",
987 handler: Handler::Leaf(|e, _| crate::editor::Editor::pane_close_pub(e)),
988 },
989 Binding {
990 keys: "up down left right tab s-tab",
991 desc: "picker navigation / arrows = hjkl everywhere",
992 section: "ex+panes",
993 live: true,
994 id: "picker-nav",
995 handler: Handler::Prefix,
996 },
997 Binding {
998 keys: "ctrl-x",
999 desc: "replace picker: exclude/include match",
1000 section: "ex+panes",
1001 live: true,
1002 id: "replace-exclude",
1003 handler: Handler::Prefix,
1004 },
1005 Binding {
1006 keys: "ctrl-l",
1007 desc: "redraw: full repaint when the terminal desyncs",
1008 section: "ex+panes",
1009 live: true,
1010 id: "redraw",
1011 handler: Handler::Leaf(|e, _| e.needs_repaint = true),
1012 },
1013];
1014
1015pub(crate) mod lookup;
1016
1017pub use lookup::{any_child, children_of, compat_report, find_row, Hint};
1018
1019#[cfg(test)]
1020mod tests;