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