From 914b5fc2b206205f86f449613e330ab6cec7d01b Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Thu, 12 Oct 2023 18:45:24 +0300 Subject: [PATCH] (mini.pick) NEW MODULE: initial commit. --- CHANGELOG.md | 4 + CONTRIBUTING.md | 16 + README.md | 2 +- doc/mini-pick.txt | 1364 +++++ doc/mini.txt | 6 + lua/mini/init.lua | 6 + lua/mini/pick.lua | 3263 +++++++++++ readmes/mini-pick.md | 332 ++ scripts/basic-setup_init.lua | 1 + scripts/dual_sync.sh | 1 + scripts/minidoc.lua | 1 + tests/dir-pick/builtin-tests/dir1/file1-1 | 5 + tests/dir-pick/builtin-tests/dir1/file1-2 | 5 + tests/dir-pick/builtin-tests/dir2/file2-1 | 5 + tests/dir-pick/builtin-tests/file | 5 + tests/dir-pick/file | 0 tests/dir-pick/lua/nvim-web-devicons.lua | 17 + tests/dir-pick/mocks/spawn.lua | 50 + tests/dir-pick/real-files/LICENSE | 1 + tests/dir-pick/real-files/Makefile | 3 + tests/dir-pick/real-files/a.lua | 5 + tests/dir-pick/real-files/b.txt | 26 + tests/dir-pick/real-files/c.gif | Bin 0 -> 137 bytes ...est_pick.lua----Pick---has-proper-complete | 23 + ...pick.lua----Pick---has-proper-complete-002 | 23 + ...pick.lua----Pick---has-proper-complete-003 | 23 + .../tests-test_pick.lua----Pick---works | 33 + .../tests-test_pick.lua----Pick---works-002 | 33 + ...st_pick.lua---Caret---moves-by-query-parts | 23 + ...ick.lua---Caret---moves-by-query-parts-002 | 23 + ...ick.lua---Caret---moves-by-query-parts-003 | 23 + .../tests-test_pick.lua---Caret---works | 23 + .../tests-test_pick.lua---Caret---works-002 | 23 + .../tests-test_pick.lua---Caret---works-003 | 23 + ...---Choose---works-for-split-tab-variations | 33 + ...hoose---works-for-split-tab-variations-002 | 33 + ...hoose---works-for-split-tab-variations-003 | 33 + ...-updated-after-moving-marking-current-item | 33 + ...ated-after-moving-marking-current-item-002 | 33 + ...ated-after-moving-marking-current-item-003 | 33 + ...ated-after-moving-marking-current-item-004 | 33 + ...lua---Info-view---respects-custom-mappings | 43 + ...---supports-vertical-and-horizontal-scroll | 33 + ...upports-vertical-and-horizontal-scroll-002 | 33 + ...upports-vertical-and-horizontal-scroll-003 | 33 + ...upports-vertical-and-horizontal-scroll-004 | 33 + .../tests-test_pick.lua---Info-view---works | 83 + ...ew---properly-computes-items-range-to-show | 17 + ...-properly-computes-items-range-to-show-002 | 17 + ...-properly-computes-items-range-to-show-003 | 17 + ...-properly-computes-items-range-to-show-004 | 17 + ...-properly-computes-items-range-to-show-005 | 17 + ...-properly-computes-items-range-to-show-006 | 17 + ...-properly-computes-items-range-to-show-007 | 17 + ...-properly-computes-items-range-to-show-008 | 17 + ...-properly-computes-items-range-to-show-009 | 17 + ...-properly-computes-items-range-to-show-010 | 17 + ...-properly-computes-items-range-to-show-011 | 17 + ...-properly-computes-items-range-to-show-012 | 17 + ...-properly-computes-items-range-to-show-013 | 17 + ...-properly-computes-items-range-to-show-014 | 17 + ...-properly-computes-items-range-to-show-015 | 17 + ...-properly-computes-items-range-to-show-016 | 17 + ...-properly-computes-items-range-to-show-017 | 17 + ...-properly-computes-items-range-to-show-018 | 17 + ...-properly-computes-items-range-to-show-019 | 17 + ...-properly-computes-items-range-to-show-020 | 17 + ...-properly-computes-items-range-to-show-021 | 17 + ...-properly-computes-items-range-to-show-022 | 17 + ...-properly-computes-items-range-to-show-023 | 17 + ...-properly-computes-items-range-to-show-024 | 17 + ...-properly-computes-items-range-to-show-025 | 17 + ...n-view---shows-marked-items-across-queries | 23 + ...ew---shows-marked-items-across-queries-002 | 23 + ...a---Main-view---supports-horizontal-scroll | 23 + ...Main-view---supports-horizontal-scroll-002 | 23 + ...Main-view---supports-horizontal-scroll-003 | 23 + ...Main-view---supports-horizontal-scroll-004 | 23 + ...Main-view---supports-horizontal-scroll-005 | 23 + ...Main-view---supports-horizontal-scroll-006 | 23 + ...ew---works-with-`content_from_bottom`=true | 23 + ...-works-with-`content_from_bottom`=true-002 | 23 + ...-works-with-`content_from_bottom`=true-003 | 23 + ...-works-with-`content_from_bottom`=true-004 | 23 + ...-works-with-`content_from_bottom`=true-005 | 23 + ...-works-with-`content_from_bottom`=true-006 | 23 + ...-works-with-`content_from_bottom`=true-007 | 23 + ...-works-with-`content_from_bottom`=true-008 | 23 + ...-works-with-`content_from_bottom`=true-009 | 23 + ...-works-with-`content_from_bottom`=true-010 | 23 + ..._pick.lua---Mark---works-without-items-set | 13 + ...k.lua---Move---works-when-no-items-are-set | 13 + ...a---Overall-view---allows-'none'-as-border | 33 + ...verall-view---allows-very-large-dimensions | 33 + ...view---correctly-infers-footer-empty-space | 33 + ...---correctly-infers-footer-empty-space-002 | 33 + ...-does-not-show-footer-if-items-are-not-set | 33 + ...ew---is-shown-over-number-and-sign-columns | 23 + ...-`options.content_from_bottom`-with-footer | 33 + ...-respects-tabline,-statusline,-'cmdheight' | 23 + ...pects-tabline,-statusline,-'cmdheight'-002 | 23 + ...pects-tabline,-statusline,-'cmdheight'-003 | 23 + ...pects-tabline,-statusline,-'cmdheight'-004 | 23 + ...pects-tabline,-statusline,-'cmdheight'-005 | 23 + ...pects-tabline,-statusline,-'cmdheight'-006 | 23 + ...est_pick.lua---Overall-view---shows-prompt | 23 + ...pick.lua---Overall-view---shows-prompt-002 | 23 + ...pick.lua---Overall-view---shows-prompt-003 | 23 + ...pick.lua---Overall-view---shows-prompt-004 | 23 + ...pick.lua---Overall-view---shows-prompt-005 | 23 + ...lua---Overall-view---truncates-border-text | 23 + ...--Overall-view---truncates-border-text-002 | 23 + ...-Overall-view---uses-footer-for-extra-info | 33 + ...rall-view---uses-footer-for-extra-info-002 | 33 + ...rall-view---uses-footer-for-extra-info-003 | 33 + ...rall-view---uses-footer-for-extra-info-004 | 33 + ...rall-view---uses-footer-for-extra-info-005 | 33 + ...rall-view---uses-footer-for-extra-info-006 | 33 + ...lay.async`-when-waiting-for-register-label | 33 + ...async`-when-waiting-for-register-label-002 | 33 + ...async`-when-waiting-for-register-label-003 | 33 + ...async`-when-waiting-for-register-label-004 | 33 + .../tests-test_pick.lua---Paste---works | 13 + .../tests-test_pick.lua---Paste---works-002 | 13 + .../tests-test_pick.lua---Paste---works-003 | 13 + ...iew---is-updated-after-moving-current-item | 33 + ...--is-updated-after-moving-current-item-002 | 33 + ...---supports-vertical-and-horizontal-scroll | 33 + ...upports-vertical-and-horizontal-scroll-002 | 33 + ...upports-vertical-and-horizontal-scroll-003 | 33 + ...upports-vertical-and-horizontal-scroll-004 | 33 + .../tests-test_pick.lua---Preview---works | 33 + .../tests-test_pick.lua---Refine---works | 23 + .../tests-test_pick.lua---Refine---works-002 | 23 + .../tests-test_pick.lua---Refine---works-003 | 23 + ...lua---Refine---works-when-no-items-are-set | 13 + ...()---respects-`local_opts.include_current` | 23 + ...)---respects-`local_opts.include_unlisted` | 33 + ...ers()---respects-`source.show`-from-config | 33 + ...-test_pick.lua---builtin.buffers()---works | 23 + ...les()---respects-`source.show`-from-config | 23 + ...ts-test_pick.lua---builtin.files()---works | 23 + ...rep()---respects-`source.show`-from-config | 23 + ...sts-test_pick.lua---builtin.grep()---works | 23 + ...ive()---respects-`source.show`-from-config | 23 + ...est_pick.lua---builtin.grep_live()---works | 23 + ....help()---handles-consecutive-applications | 33 + ....lua---builtin.help()---has-proper-preview | 33 + ...sts-test_pick.lua---builtin.help()---works | 33 + ...test_pick.lua---builtin.help()---works-002 | 33 + ...orks-for-help-tags-with-special-characters | 33 + ...---works-when-help-window-is-alreay-opened | 33 + ...s-test_pick.lua---builtin.resume()---works | 33 + ...ault_match()---does-not-block-query-update | 33 + ...default_match()---works-with-active-picker | 33 + ...ult_match()---works-with-active-picker-002 | 33 + ...ick.lua---default_preview()---has-fallback | 23 + ...lua---default_preview()---has-fallback-002 | 23 + ...view()---has-syntax-highlighting-in-buffer | 33 + ...()---has-syntax-highlighting-in-buffer-002 | 33 + ...w()---has-syntax-highlighting-in-file-path | 33 + ...--has-syntax-highlighting-in-file-path-002 | 33 + ...efault_preview()---loads-context-in-buffer | 33 + ...lt_preview()---loads-context-in-buffer-002 | 33 + ...lt_preview()---loads-context-in-buffer-003 | 33 + ...ult_preview()---loads-context-in-file-path | 33 + ...preview()---loads-context-in-file-path-002 | 33 + ...preview()---loads-context-in-file-path-003 | 33 + ...pts.line_position`---1-+-args-{-'bottom'-} | 33 + ...line_position`---1-+-args-{-'bottom'-}-002 | 33 + ...pts.line_position`---1-+-args-{-'center'-} | 33 + ...line_position`---1-+-args-{-'center'-}-002 | 33 + ...-`opts.line_position`---1-+-args-{-'top'-} | 33 + ...ts.line_position`---1-+-args-{-'top'-}-002 | 33 + ...review()---respects-`opts.n_context_lines` | 33 + ...ew()---respects-`opts.n_context_lines`-002 | 33 + ...-default_preview()---respects-`source.cwd` | 33 + ...--default_preview()---shows-line-in-buffer | 33 + ...efault_preview()---shows-line-in-file-path | 33 + ...lt_preview()---shows-line-in-file-path-002 | 33 + ...lt_preview()---shows-line-in-file-path-003 | 33 + ...fault_preview()---shows-position-in-buffer | 33 + ...lt_preview()---shows-position-in-file-path | 33 + ...review()---shows-position-in-file-path-002 | 33 + ...review()---shows-position-in-file-path-003 | 33 + ...default_preview()---shows-region-in-buffer | 33 + ...ult_preview()---shows-region-in-buffer-002 | 33 + ...ault_preview()---shows-region-in-file-path | 33 + ..._preview()---shows-region-in-file-path-002 | 33 + ...-test_pick.lua---default_preview()---works | 33 + ...lua---default_preview()---works-for-buffer | 33 + ...--default_preview()---works-for-buffer-002 | 33 + ...--default_preview()---works-for-buffer-003 | 33 + ...--default_preview()---works-for-buffer-004 | 33 + ...--default_preview()---works-for-buffer-005 | 33 + ...fault_preview()---works-for-directory-path | 33 + ...t_preview()---works-for-directory-path-002 | 33 + ...---default_preview()---works-for-file-path | 33 + ...efault_preview()---works-for-file-path-002 | 33 + ...efault_preview()---works-for-file-path-003 | 33 + ...lt_preview()---works-without-active-picker | 33 + ...review()---works-without-active-picker-002 | 33 + ...--handles-query-similar-to-`default_match` | 33 + ...ndles-query-similar-to-`default_match`-002 | 33 + ...ndles-query-similar-to-`default_match`-003 | 33 + ...ndles-query-similar-to-`default_match`-004 | 33 + ...ndles-query-similar-to-`default_match`-005 | 33 + ...ndles-stritems-with-non-trivial-whitespace | 23 + ...show()---respects-'ignorecase'-'smartcase' | 17 + ...()---respects-'ignorecase'-'smartcase'-002 | 17 + ...()---respects-'ignorecase'-'smartcase'-003 | 17 + ...()---respects-'ignorecase'-'smartcase'-004 | 17 + ...()---respects-'ignorecase'-'smartcase'-005 | 17 + ...()---respects-'ignorecase'-'smartcase'-006 | 17 + ...efault_show()---respects-`opts.show_icons` | 23 + ...lt_show()---respects-`opts.show_icons`-002 | 23 + ...ck.lua---default_show()---shows-best-match | 23 + ...ua---default_show()---shows-best-match-002 | 23 + ...sts-test_pick.lua---default_show()---works | 33 + ...t_show()---works-with-multibyte-characters | 23 + ...ow()---works-with-multibyte-characters-002 | 23 + ...works-with-non-single-char-entries-queries | 23 + ...s-with-non-single-char-entries-queries-002 | 23 + ...s-with-non-single-char-entries-queries-003 | 23 + ...fault_show()---works-without-active-picker | 23 + ...t_show()---works-without-active-picker-002 | 23 + ...ua---refresh()---is-called-on-`VimResized` | 33 + ...-refresh()---is-called-on-`VimResized`-002 | 33 + ...lua---refresh()---recomputes-window-config | 33 + ...--refresh()---recomputes-window-config-002 | 33 + .../tests-test_pick.lua---refresh()---works | 33 + ...ests-test_pick.lua---refresh()---works-002 | 33 + ...pick.lua---set_picker_match_inds()---works | 33 + ...-test_pick.lua---set_picker_opts()---works | 33 + ...t_pick.lua---set_picker_opts()---works-002 | 33 + ...t_pick.lua---set_picker_opts()---works-003 | 33 + ...test_pick.lua---set_picker_query()---works | 33 + ...()---can-be-started-without-explicit-items | 33 + ...ua---start()---correctly-computes-stritems | 33 + ...ick.lua---start()---respects-`delay.async` | 33 + ...lua---start()---respects-`delay.async`-002 | 33 + ...lua---start()---respects-`delay.async`-003 | 33 + ...lua---start()---respects-`delay.async`-004 | 33 + ...)---respects-`options.content_from_bottom` | 33 + ...ck.lua---start()---respects-`source.items` | 33 + ...ua---start()---respects-`source.items`-002 | 33 + ...ua---start()---respects-`source.items`-003 | 33 + ...ua---start()---respects-`source.items`-004 | 33 + ...ck.lua---start()---respects-`source.match` | 33 + ...ick.lua---start()---respects-`source.name` | 33 + ....lua---start()---respects-`source.preview` | 33 + ...---start()---respects-`source.preview`-002 | 33 + ...ick.lua---start()---respects-`source.show` | 33 + ...lua---start()---respects-`source.show`-002 | 33 + ...start()---respects-`vim.b.minipick_config` | 33 + ...k.lua---start()---respects-`window.config` | 33 + ...a---start()---respects-`window.config`-002 | 33 + ...ick.lua---start()---respects-global-config | 33 + ...---start()---stops-currently-active-picker | 33 + ...---stops-impoperly-aborted-previous-picker | 33 + ...tops-impoperly-aborted-previous-picker-002 | 33 + ...est_pick.lua---start()---tracks-lost-focus | 33 + ...pick.lua---start()---tracks-lost-focus-002 | 33 + .../tests-test_pick.lua---start()---works | 33 + .../tests-test_pick.lua---start()---works-002 | 33 + ...t_pick.lua---start()---works-on-Neovim-0.9 | 33 + ...ck.lua---start()---works-on-Neovim-0.9-002 | 33 + ...k.lua---start()---works-with-window-footer | 33 + ...a---start()---works-with-window-footer-002 | 33 + .../tests-test_pick.lua---stop()---works | 33 + .../tests-test_pick.lua---stop()---works-002 | 33 + ...ui_select()---respects-`opts.preview_item` | 33 + ...ct()---shows-only-original-item-in-preview | 33 + .../tests-test_pick.lua---ui_select()---works | 33 + tests/test_pick.lua | 4994 +++++++++++++++++ 275 files changed, 17178 insertions(+), 1 deletion(-) create mode 100644 doc/mini-pick.txt create mode 100644 lua/mini/pick.lua create mode 100644 readmes/mini-pick.md create mode 100644 tests/dir-pick/builtin-tests/dir1/file1-1 create mode 100644 tests/dir-pick/builtin-tests/dir1/file1-2 create mode 100644 tests/dir-pick/builtin-tests/dir2/file2-1 create mode 100644 tests/dir-pick/builtin-tests/file create mode 100644 tests/dir-pick/file create mode 100644 tests/dir-pick/lua/nvim-web-devicons.lua create mode 100644 tests/dir-pick/mocks/spawn.lua create mode 100644 tests/dir-pick/real-files/LICENSE create mode 100644 tests/dir-pick/real-files/Makefile create mode 100644 tests/dir-pick/real-files/a.lua create mode 100644 tests/dir-pick/real-files/b.txt create mode 100644 tests/dir-pick/real-files/c.gif create mode 100644 tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete create mode 100644 tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-002 create mode 100644 tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-003 create mode 100644 tests/screenshots/tests-test_pick.lua----Pick---works create mode 100644 tests/screenshots/tests-test_pick.lua----Pick---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---works create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Caret---works-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations create mode 100644 tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---respects-custom-mappings create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Info-view---works create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-006 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-007 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-008 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-009 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-010 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-011 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-012 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-013 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-014 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-015 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-016 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-017 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-018 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-019 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-020 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-021 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-022 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-023 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-024 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-025 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-006 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-006 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-007 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-008 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-009 create mode 100644 tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-010 create mode 100644 tests/screenshots/tests-test_pick.lua---Mark---works-without-items-set create mode 100644 tests/screenshots/tests-test_pick.lua---Move---works-when-no-items-are-set create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---allows-'none'-as-border create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---allows-very-large-dimensions create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---does-not-show-footer-if-items-are-not-set create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---is-shown-over-number-and-sign-columns create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-`options.content_from_bottom`-with-footer create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight' create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-006 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-005 create mode 100644 tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-006 create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---works create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Paste---works-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-004 create mode 100644 tests/screenshots/tests-test_pick.lua---Preview---works create mode 100644 tests/screenshots/tests-test_pick.lua---Refine---works create mode 100644 tests/screenshots/tests-test_pick.lua---Refine---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---Refine---works-003 create mode 100644 tests/screenshots/tests-test_pick.lua---Refine---works-when-no-items-are-set create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_current` create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_unlisted` create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`source.show`-from-config create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.buffers()---works create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.files()---respects-`source.show`-from-config create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.files()---works create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.grep()---respects-`source.show`-from-config create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.grep()---works create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.grep_live()---respects-`source.show`-from-config create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.grep_live()---works create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---handles-consecutive-applications create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---has-proper-preview create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---works create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---works-for-help-tags-with-special-characters create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.help()---works-when-help-window-is-alreay-opened create mode 100644 tests/screenshots/tests-test_pick.lua---builtin.resume()---works create mode 100644 tests/screenshots/tests-test_pick.lua---default_match()---does-not-block-query-update create mode 100644 tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker create mode 100644 tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-} create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-}-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-} create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-}-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-} create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-}-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines` create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---respects-`source.cwd` create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-004 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-005 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker create mode 100644 tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match` create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-004 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-005 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---handles-stritems-with-non-trivial-whitespace create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase' create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-004 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-005 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-006 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons` create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-002 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-003 create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker create mode 100644 tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker-002 create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized` create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config-002 create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---works create mode 100644 tests/screenshots/tests-test_pick.lua---refresh()---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---set_picker_match_inds()---works create mode 100644 tests/screenshots/tests-test_pick.lua---set_picker_opts()---works create mode 100644 tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-003 create mode 100644 tests/screenshots/tests-test_pick.lua---set_picker_query()---works create mode 100644 tests/screenshots/tests-test_pick.lua---start()---can-be-started-without-explicit-items create mode 100644 tests/screenshots/tests-test_pick.lua---start()---correctly-computes-stritems create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-003 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-004 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`options.content_from_bottom` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.items` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-003 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-004 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.match` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.name` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.show` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`source.show`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`vim.b.minipick_config` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`window.config` create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-`window.config`-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---respects-global-config create mode 100644 tests/screenshots/tests-test_pick.lua---start()---stops-currently-active-picker create mode 100644 tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker create mode 100644 tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus create mode 100644 tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9-002 create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer create mode 100644 tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer-002 create mode 100644 tests/screenshots/tests-test_pick.lua---stop()---works create mode 100644 tests/screenshots/tests-test_pick.lua---stop()---works-002 create mode 100644 tests/screenshots/tests-test_pick.lua---ui_select()---respects-`opts.preview_item` create mode 100644 tests/screenshots/tests-test_pick.lua---ui_select()---shows-only-original-item-in-preview create mode 100644 tests/screenshots/tests-test_pick.lua---ui_select()---works create mode 100644 tests/test_pick.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 787e96d5..284bc711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ - BREAKING: Stop supporting deprecated 'HiPhish/nvim-ts-rainbow2'. +## mini.pick + +Introduction of a new module. + # Version 0.10.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0dffe914..32a47365 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -133,6 +133,22 @@ Here is a list of all highlight groups defined inside 'mini.nvim' modules. See d - 'mini.operators': - `MiniOperatorsExchangeFrom` +- 'mini.pick': + + - `MiniPickBorder` + - `MiniPickBorderBusy` + - `MiniPickBorderText` + - `MiniPickIconDirectory` + - `MiniPickIconFile` + - `MiniPickHeader` + - `MiniPickMatchCurrent` + - `MiniPickMatchMarked` + - `MiniPickMatchRanges` + - `MiniPickNormal` + - `MiniPickPreviewLine` + - `MiniPickPreviewRegion` + - `MiniPickPrompt` + - 'mini.starter': - `MiniStarterCurrent` - `MiniStarterFooter` diff --git a/README.md b/README.md index e5af2493..c0e345ad 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Here are code snippets for some common installation methods: | mini.move | Move any selection in any direction | [README](readmes/mini-move.md) | [Help file](doc/mini-move.txt) | | mini.operators | Text edit operators | [README](readmes/mini-operators.md) | [Help file](doc/mini-operators.txt) | | mini.pairs | Autopairs | [README](readmes/mini-pairs.md) | [Help file](doc/mini-pairs.txt) | +| mini.pick | Pick anything | [README](readmes/mini-pick.md) | [Help file](doc/mini-pick.txt) | | mini.sessions | Session management | [README](readmes/mini-sessions.md) | [Help file](doc/mini-sessions.txt) | | mini.splitjoin | Split and join arguments | [README](readmes/mini-splitjoin.md) | [Help file](doc/mini-splitjoin.txt) | | mini.starter | Start screen | [README](readmes/mini-starter.md) | [Help file](doc/mini-starter.txt) | @@ -141,7 +142,6 @@ This is the list of modules I currently intend to implement eventually (as my fr - 'mini.git' - utilities for more convenient work with Git. Actual scope is to be defined. - 'mini.keymap' - utilities to make non-trivial mappings (like [max397574/better-escape.nvim](https://github.com/max397574/better-escape.nvim) and dot-repeatable mappings). - 'mini.notify' - minimal UI to show Neovim notifications (like coming from LSP server, etc.). -- 'mini.pick' - fuzzy picker. A very simplified version of [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim). - 'mini.places' - persistent track of common places per working directory. Something like [ThePrimeagen/harpoon](https://github.com/ThePrimeagen/harpoon). - 'mini.snippets' - work with snippets. Something like [L3MON4D3/LuaSnip](https://github.com/L3MON4D3/LuaSnip) but only with more straightforward functionality. - 'mini.statuscolumn' - customizable 'statuscolumn'. diff --git a/doc/mini-pick.txt b/doc/mini-pick.txt new file mode 100644 index 00000000..98eda345 --- /dev/null +++ b/doc/mini-pick.txt @@ -0,0 +1,1364 @@ +*mini.pick* Pick anything +*MiniPick* + +MIT License Copyright (c) 2023 Evgeni Chasnovski + +============================================================================== + +Features: + +- Single window general purpose interface for picking element from any array. + +- On demand toggleable preview and info views. + +- Interactive query matching (filter+sort) with fast non-blocking default + which does fuzzy matching and allows other modes (|MiniPick.default_match()|). + +- Built-in pickers (see |MiniPick.builtin|): + - Files. + - Pattern match (for fixed pattern and with live feedback). + - Buffers. + - Help tags. + - CLI output. + - Resume latest picker. + +- |:Pick| command to work with extensible |MiniPick.registry|. + +- |vim.ui.select()| wrapper (see |MiniPick.ui_select()|). + +- Rich and customizable built-in |MiniPick-actions| when picker is active: + - Manually change currently focused item. + - Scroll vertically and horizontally. + - Toggle preview or info view. + - Mark/unmark items to choose later. + - Refine current matches (make them part of a new picker). + - And many more. + +- Minimal yet flexible |MiniPick-source| specification with: + - Items (array, callable, or manually set later). + - Source name. + - Working directory. + - Matching algorithm. + - Way matches are shown in main window. + - Item preview. + - "On choice" action for current and marked items. + +- Custom actions/keys can be configured globally, per buffer, or per picker. + +- Out of the box support for 'ignorecase' and 'smartcase'. + +- Match caching to increase responsiveness on repeated prompts. + +Notes: +- Works on all supported versions but using Neovim>=0.9 is recommended. + Neovim>=0.10 will give more visual feedback in floating window footer. + +Sources with more details: +- |MiniPick-overview| +- |MiniPick-source| +- |MiniPick-actions| +- |MiniPick-examples| +- |MiniPick.builtin| + +# Dependencies ~ + +Suggested dependencies (provide extra functionality, will work without them): + +- Plugin 'nvim-tree/nvim-web-devicons' for filetype icons near the items + representing actual paths. If missing, default or no icons will be used. + + *MiniPick-cli-tools* +- CLI tool(s) to power |MiniPick.builtin.files()|, |MiniPick.builtin.grep()|, and + |MiniPick.builtin.grep_live()| built-in pickers: + - `rg` ('github.com/BurntSushi/ripgrep'; enough for all three; recommended). + - `fd` ('github.com/sharkdp/fd'; for `files` only). + - `git` ('github.com/git/git'; enough for all three). + +# Setup ~ + +This module needs a setup with `require('mini.pick').setup({})` (replace +`{}` with your `config` table). It will create global Lua table `MiniPick` +which you can use for scripting or manually (with `:lua MiniPick.*`). + +See |MiniPick.config| for available config settings. + +You can override runtime config settings locally to buffer inside +`vim.b.minioperators_config` which should have same structure as +`MiniPick.config`. See |mini.nvim-buffer-local-config| for more details. + +# Comparisons ~ + +- 'nvim-telescope/telescope.nvim': + - The main inspiration for this module, so there is significant overlap. + - Has three (or two) window UI (prompt, matches, preview), while this + module combines everything in one window. It allows more straightforward + customization for unusual scenarios. + - Default match algorithm is somewhat slow, while this module should + match relatively lag-free for at least 100K+ items. + - Has many built-in pickers, while this module has handful at its core + relying on other 'mini.nvim' modules to provide more. + +- 'ibhagwan/fzf-lua': + - Mostly same comparison as with 'nvim-telescope/telescope.nvim'. + - Requires 'junegunn/fzf' installed to power fuzzy matching, while this + module provides built-in Lua matching. + +# Highlight groups ~ + +* `MiniPickBorder` - window border. +* `MiniPickBorderBusy` - window border while picker is busy processing. +* `MiniPickBorderText` - non-prompt on border. +* `MiniPickIconDirectory` - default icon for directory. +* `MiniPickIconFile` - default icon for file. +* `MiniPickHeader` - headers in info buffer and previews. +* `MiniPickMatchCurrent` - current matched item. +* `MiniPickMatchMarked` - marked matched items. +* `MiniPickMatchRanges` - ranges matching query elements. +* `MiniPickNormal` - basic foreground/background highlighting. +* `MiniPickPreviewLine` - target line in preview. +* `MiniPickPreviewRegion` - target region in preview. +* `MiniPickPrompt` - prompt. + +To change any highlight group, modify it directly with |:highlight|. + +------------------------------------------------------------------------------ + *MiniPick-events* +Events ~ + +To allow user customization and integration of external tools, certain |User| +autocommand events are triggered under common circumstances: + +- `MiniPickStart` - just after picker has started. +- `MiniPickStop` - just before picker is stopped. + +------------------------------------------------------------------------------ + *MiniPick-overview* +# Overview ~ + +General idea is to take array of objects, display them with interactive +filter/sort/navigate/preview, and allow to choose one or more items. + +## How to start a picker ~ + +- Use |MiniPick.start()| with `opts.source` defining |MiniPick-source|. + Example: `MiniPick.start({ source = { items = vim.fn.readdir('.') } })` + +- Use any of |MiniPick.builtin| pickers directly. + Example: `MiniPick.builtin.files({ tool = 'git' })` + +- Use |:Pick| command which uses customizable pickers from |MiniPick.registry|. + Example: `:Pick files tool=git` + +## User interface ~ + +UI consists from a single window capable of displaying three different views: +- "Main" - where current query matches are shown. +- "Preview" - preview of current item (toggle with ``). +- "Info" - general info about picker and its state (toggle with ``). + +Current prompt is displayed (in Neovim>=0.9) at the top left of the window +border with vertical line indicating caret (current input position). + +Bottom part of window border displays (in Neovim>=0.10) extra visual feedback: +- Left part is a picker name. +- Right part contains information in the format > + | | / + +When picker is busy (like if there are no items yet set or matching is active) +window border changes color to be `MiniPickBorderBusy` after `config.delay.busy` +milliseconds of idle time. + +## Life cycle ~ + +- Type characters to filter and sort matches. It uses |MiniPick.default_match()| + with `query` being an array of pressed characters. + Overview of how it matches: + - If query starts with `'`, the match is exact. + - If query starts with `^`, the match is exact at start. + - If query starts with `$`, the match is exact at end. + - If query starts with `*`, the match is forced to be fuzzy. + - Otherwise match is fuzzy. + - Sorting is done to first minimize match width and then match start. + Nothing more: no favoring certain places in string, etc. + +- Type special keys to perform |MiniPick-actions|. Here are some basic ones: + - `` / `` moves down; `` / `` moves up. + - `` / `` moves prompt caret left / right. + - `` toggles information window with all available mappings. + - `` toggles preview. + - `` / `` toggles current / all item(s) as (un)marked. + - `` / `` makes all matches or marked items as new picker. + - `` / `` chooses current/marked item(s). + - `` / `` stops picker. + +## Implementation details ~ + +- Any picker is non-blocking but waits to return the chosen item. Example: + `file = MiniPick.builtin.files()` allows other actions to be executed when + picker is shown while still assigning `file` with value of the chosen item. + +------------------------------------------------------------------------------ + *MiniPick-source* +Source is defined as a `source` field inside one of (in increasing priority): +- |MiniPick.config| - has global effect. +- |vim.b.minipick_config| - has buffer-local effect. +- `opts.source` in picker call - has effect for that particular call. + +Example of source to choose from |arglist|: > + { items = vim.fn.argv, name = 'Arglist' } +< + +Note: this is mostly useful for writing pickers. Can safely skip if you +want to just use provided pickers. + + *MiniPick-source.items* +# Items ~ + +`source.items` defines items to choose from. It should be one of the following: +- Array of objects which can have different types. Any type is allowed. +- `nil`. Picker waits for explicit |MiniPick.set_picker_items()| call. +- Callable returning any of the previous types. Will be called once on start. + + *MiniPick-source.items-stritems* +Matching is done for items array based on the string representation of its +elements (here called "stritems"). For single item it is computed as follows: +- Callable is called once with output used in next steps. +- String item is used as is. +- String field of table item is used (if present). +- Use output of |vim.inspect()|. + +Example: > + + items = { 'aaa.txt', { text = 'bbb' }, function() return 'ccc' end } + -- corresponding stritems are { 'aaa.txt', 'bbb', 'ccc' } + +Default value is `nil`, assuming it always be supplied by the caller. + + *MiniPick-source.items-common* +There are some recommendations for common item types in order for them to work +out of the box with |MiniPick.default_show()|, |MiniPick.default_preview()|, +|MiniPick.default_choose()|, |MiniPick.default_choose_marked()|: + +- Path (file or directory). Use string or `path` field of a table. Path can + be either absolute or relative to the `source.cwd`. + Examples: `'aaa.txt'`, `{ path = 'aaa.txt' }` + +- Buffer. Use buffer id as number, string, or `bufnr` / `buf_id` / `buf` + field of a table (any name is allowed). + Examples: `1`, `'1'`, `{ bufnr = 1 }`, `{ buf_id = 1 }`, `{ buf = 1 }` + +- Line in file or buffer. Use table representation with `lnum` field with line + number (starting from 1). Files can use string in ":" format. + Examples: > + { path = 'aaa.txt', lnum = 2 }, 'aaa.txt:2', { path = 'aaa.txt:2' }, + { bufnr = 1, lnum = 3 } + +- Position in file or buffer. Use table representation with `lnum` and `col` + fields with line and column numbers (starting from 1). Files can use string + in "::" format. + Examples: > + { path = 'aaa.txt', lnum = 2, col = 3 }, 'aaa.txt:2:3', + { path = 'aaa.txt:2:3' }, { bufnr = 1, lnum = 3, col = 4 } + +- Region in file or buffer. Use table representation with `lnum`, `col`, + `end_lnum`, `end_col` fields for start and end line/column. All numbers + start from 1, end line is inclusive, end column is exclusive. + This naming is similar to |getqflist()| and |diagnostic-structure|. + Examples: > + { path = 'aaa.txt', lnum = 2, col = 3, end_lnum = 4, end_col = 5 }, + { bufnr = 1, lnum = 3, col = 4, end_lnum = 5, end_col = 6 } + +Note: all table items will benefit from having `text` field for better matching. + + *MiniPick-source.name* +# Name ~ + +`source.name` defines the name of the picker to be used for visual feedback. + +Default value is "". + + *MiniPick-source.cwd* +# Current working directory ~ + +`source.cwd` is a string defining the current working directory in which +picker operates. It should point to a valid actually present directory path. +This is a part of source to allow persistent way to use relative paths, +i.e. not depend on current directory being constant after picker start. +It also makes the |MiniPick.builtin.resume()| picker more robust. + +Default value is |current-directory|. + + *MiniPick-source.match* +# Match ~ + +`source.match` is a callable defining how stritems +(see |MiniPick-source.items-stritems|) are matched (filetered and sorted) based +on the query. + +It will be called with the following arguments: +- `stritems` - all available stritems for current picker. +- `inds` - array of `stritems` indexes usually pointing at current matches. + It does point to current matches in the case of interactively appending + character at the end of the query. It assumes that matches for such bigger + query is a subset of previous matches (implementation can ignore it). + This can be utilized to increase performance by checking fewer stritems. +- `query` - array of strings. Usually (like is common case of user interactively + typing query) each string represents one character. However, any strings are + allowed, as query can be set with |MiniPick.set_picker_query()|. + +It should either return array of match indexes for stritems elements matching +the query (synchronous) or explicitly use |MiniPick.set_picker_match_inds()| +to set them (may be asynchronous). + +Notes: +- The result can be any array of `stritems` indexes, i.e. not necessarily + a subset of input `inds`. + +- Both `stritems` and `query` depend on values of 'ignorecase' and 'smartcase'. + If query shows "ignore case" properties (only 'ignorecase' is set or both + 'ignorecase' / 'smartcase' are set and query has only lowercase characters), + then `stritems` and `query` will have only lowercase characters. + This allows automatic support for case insensitive matching while being + faster and having simpler match function implementation. + +- Writing custom `source.match` usually means also changing |MiniPick-source.show| + because it is used to highlight stritems parts actually matching the query. + +Example of simple "exact" `match()` preserving initial order: > + + local match_exact = function(stritems, inds, query) + local prompt_pattern = vim.pesc(table.concat(query)) + local f = function(i) return stritems[i]:find(prompt_pattern) ~= nil end + return vim.tbl_filter(f, inds) + end +< + For non-blocking version see |MiniPick.poke_is_picker_active()|. + +Default value is |MiniPick.default_match()|. + + *MiniPick-source.show* +# Show ~ + +`source.show` is a callable defining how matched items are shown in the window. + +It will be called with the following arguments: +- `buf_id` - identifier of the target buffer. +- `items_to_show` - array of actual items to be shown in `buf_id`. This is + a subset of currently matched items computed to fit in current window view. +- `query` - array of strings. Same as in `source.match`. + +It should update buffer `buf_id` to visually represent `items_to_show` +__one item per line starting from line one__ (it shouldn't depend on +`options.content_from_bottom`). This also includes possible visualization +of which parts of stritem actually matched query. + +Example (assuming string items; without highlighting): > + + local show_prepend = function(buf_id, items_arr, query) + local lines = vim.tbl_map(function(x) return 'Item: ' .. x end, items_arr) + vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) + end + +Default value is |MiniPick.default_show()|. + + *MiniPick-source.preview* +# Preview ~ + +`source.preview` is a callable defining how item preview is done. + +It will be called with the following arguments: +- `buf_id` - identifier of the target buffer. Note: for every separate instance + of item previewing new scratch buffer is be created. +- `item` - item to preview. + +It should update buffer `buf_id` to visually represent `item`. + +Example: > + + local preview_inspect = function(buf_id, item) + local lines = vim.split(vim.inspect(item), '\n') + vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) + end + +Default value is |MiniPick.default_preview()|. + + *MiniPick-source.choose* +# Choose an item ~ + +`source.choose` is a callable defining what to do when an item is chosen. + +It will be called with the following arguments: +- `item` - chosen item. Always non-`nil`. + +It should perform any intended "choose" action for an item and return +a value indicating whether picker should continue (i.e. not stop): +`nil` and `false` will stop picker, other values will continue. + +Notes: +- It is called when picker window is still current. Use `windows.target` value + from |MiniPick.get_picker_state()| output to do something with target window. + +Example: > + + local choose_file_continue = function(item) + if vim.fn.filereadable(item) == 0 then return end + vim.api.nvim_win_call( + MiniPick.get_picker_state().windows.main, + function() vim.cmd('edit ' .. item) end + ) + return true + end + +Default value is |MiniPick.default_choose()|. + + *MiniPick-source.choose_marked* +# Choose marked items ~ + +`source.choose_marked` is a callable defining what to do when marked items +(see |MiniPick-actions-mark|) are chosen. Serves as a companion to +`source.choose` which can choose several items. + +It will be called with the following arguments: +- `items_marked` - array of marked items. Can be empty. + +It should perform any intended "choose" action for several items and return +a value indicating whether picker should continue (i.e. not stop): +`nil` and `false` will stop picker, other values will continue. + +Notes: +- It is called when picker window is still current. Use `windows.target` value + from |MiniPick.get_picker_state()| output to do something with target window. + +Example: > + + local choose_marked_print = function(items) print(vim.inspect(items)) end + +Default value is |MiniPick.default_choose_marked()|. + +------------------------------------------------------------------------------ + *MiniPick-actions* +When picker is active, `mappings` table defines a set of special keys which when +pressed will execute certain actions. Those can be of two types: +- Built-in: actions present in default `config.mappings`. Can be only overridden + with a different key. +- Custom: user defined actions. Should be a table with `char` and `func` fields. + + +# Built-in ~ + *MiniPick-actions-caret* +## Caret ~ + +User can add character not only at query end, but more generally at caret. + +- `mappings.caret_left` - move caret to left. +- `mappings.caret_right` - move caret to right. + + *MiniPick-actions-choose* +## Choose ~ + +Choose is a fundamental action that actually implements the intent of +calling a picker, i.e. pick an item. + +- `mappings.choose` - choose as is, i.e. apply `source.choose` for current item. +- `mappings.choose_in_split` - make horizontal split at target window, update + target window to the new split, and choose. +- `mappings.choose_in_tabpage` - same as `choose_in_split`, but create tabpage. +- `mappings.choose_in_vsplit` - same as `choose_in_split`, but split vertically. +- `mappings.choose_marked` - choose marked items as is, i.e. + apply `source.choose_marked` at current marked items. + + *MiniPick-actions-delete* +## Delete ~ + +Delete actions are for deleting elements from query. + +- `mappings.delete_char` - delete one character to the left. +- `mappings.delete_char_right` - delete one character to the right. +- `mappings.delete_left` - delete everything to the left (like |i_CTRL-U|). +- `mappings.delete_word` - delete word to the left (like |i_CTRL-W|). + + *MiniPick-actions-mark* +## Mark ~ + +Marking is an action of adding certain items to a separate list which then can +be chosen with `mappings.choose_marked` (for example, sent to quickfix list). +This is a companion to a regular choosing which can pick only one item. + +- `mappings.mark` - toggle marked/unmarked state of current item. +- `mappings.mark_all` - toggle marked/unmarked state (mark all if not all + marked; unmark all otherwise) of all currently matched items. + +Notes: +- Marks persist across queries and matches. For example, user can make a query + with marking all matches several times and marked items from all queries + will be preserved. + + *MiniPick-actions-move* +## Move ~ + +Move is a fundamental action of changing which item is current. + +- `mappings.move_down` - change focus to the item below. +- `mappings.move_start` change focus to the first currently matched item +- `mappings.move_up` - change focus to the item above. + +Notes: +- Up and down wrap around edges: `move_down` on last item moves to first, + `move_up` on first moves to last. +- Moving when preview or info view is shown updates the view with new item. +- These also work with non-overridable alternatives: + - `` moves down. + - `` moves to first matched. + - `` moves up. + + *MiniPick-actions-paste* +## Paste ~ + +Paste is an action to paste content of |registers| at caret. + +- `mappings.paste` - paste from register defined by the next key press. + +Notes: +- Does not support expression register `=`. + + *MiniPick-actions-refine* +## Refine ~ + +Refine is an action that primarily executes the following: +- Takes certain items and makes them be all items (in order they are present). +- Resets query. +- Updates `source.match` to be the one from config. + +- `mappings.refine` - refine currently matched items. +- `mappings.refin_marked` - refine currently marked items. + +This action is useful in at least two cases: +- Perform consecutive "narrowing" queries. Example: to get items that contain + both "hello" and "world" exact matches (in no particular order) with default + matching, type "'hello" (notice "'" at the start) followed by `` and + another "'world". +- Reset `match` to default. Particularly useful in |MiniPick.builtin.grep_live()|. + + *MiniPick-actions-scroll* +## Scroll ~ + +Scroll is an action to either move current item focus further than to the +neighbor item or adjust window view to see more information. + +- `mappings.scroll_down` - when matches are shown, go down by the amount of + visible matches. In preview and info view - scroll down as with |CTRL-F|. +- `mappings.scroll_left` - scroll left as with |zH|. +- `mappings.scroll_right` - scroll right as with |zL|. +- `mappings.scroll_up` - when matches are shown, go up by the amount of + visible matches. In preview and info view - scroll up as with |CTRL-B|. + + *MiniPick-actions-stop* +## Stop ~ + +`mappings.stop` stops the picker. also always stops the picker. + + + *MiniPick-actions-toggle* +## Toggle ~ + +Toggle action is a way to change view: show if target is not shown, reset to +main view otherwise. + +- `mappings.toggle_info` - toggle info view. +- `mappings.toggle_preview` - toggle preview. + +Note: +- Updating query in any way resets window view to show matches. +- Moving current item focus keeps preview or info view with updated item. + + *MiniPick-actions-custom* +# Custom ~ + +Along with built-in actions, users can define custom actions. This can be +done by supplying custom elements to `mappings` table. The field defines action +name (used to infer an action description in info view). The value is a table +with the following fields: +- `(string)` - single character acting as action trigger. +- `(function)` - callable to be executed without arguments after + user presses . + +Example of `execute` custom mapping: > + + execute = { + char = '', + func = function() vim.cmd(vim.fn.input('Execute: ')) end, + } + +------------------------------------------------------------------------------ + *MiniPick-examples* +Common configuration examples ~ + +- Disable icons in |MiniPick.builtin| pickers related to paths: > + + local pick = require('mini.pick') + pick.setup({ source = { show = pick.default_show } }) + +- Mappings to switch `toggle_{preview,info}` and `move_{up,down}`: > + + require('mini.pick').setup({ + mappings = { + toggle_info = '', + toggle_preview = '', + move_down = '', + move_up = '', + } + }) + +- "Cursor tooltip" window style: > + + { + window = { + config = { + relative = 'cursor', anchor = 'NW', + row = 0, col = 0, width = 40, height = 20, + }, + }, + } + +- Change window border style: > + + { window = { config = { border = 'double' } } } + +------------------------------------------------------------------------------ + *MiniPick.setup()* + `MiniPick.setup`({config}) +Module setup + + *:Pick* +Calling this function creates a `:Pick` user command. It takes picker name +from |MiniPick.registry| as mandatory first argument and executes it with +following (expanded, |expandcmd()|) || combined in a single table. +To add custom pickers, update |MiniPick.registry|. + +Example: > + + :Pick files tool='git' + :Pick grep pattern='' + +Parameters~ +{config} `(table|nil)` Module config table. See |MiniPick.config|. + +Usage~ +`require('mini.pick').setup({})` (replace `{}` with your `config` table). + +------------------------------------------------------------------------------ + *MiniPick.config* + `MiniPick.config` +Module config + +Default values: +> + MiniPick.config = { + -- Delays (in ms; should be at least 1) + delay = { + -- Delay between forcing asynchronous behavior + async = 10, + + -- Delay between computation start and visual feedback about it + busy = 50, + }, + + -- Keys for performing actions. See `:h MiniPick-actions`. + mappings = { + caret_left = '', + caret_right = '', + + choose = '', + choose_in_split = '', + choose_in_tabpage = '', + choose_in_vsplit = '', + choose_marked = '', + + delete_char = '', + delete_char_right = '', + delete_left = '', + delete_word = '', + + mark = '', + mark_all = '', + + move_down = '', + move_start = '', + move_up = '', + + paste = '', + + refine = '', + refine_marked = '', + + scroll_down = '', + scroll_left = '', + scroll_right = '', + scroll_up = '', + + stop = '', + + toggle_info = '', + toggle_preview = '', + }, + + -- General options + options = { + -- Whether to show content from bottom to top + content_from_bottom = false, + + -- Whether to cache matches (more speed and memory on repeated prompts) + use_cache = false, + }, + + -- Source definition. See `:h MiniPick-source`. + source = { + items = nil, + name = nil, + cwd = nil, + + match = nil, + show = nil, + preview = nil, + + choose = nil, + choose_marked = nil, + }, + + -- Window related options + window = { + -- Float window config (table or callable returning it) + config = nil, + }, + } +< +# Delays ~ + +`config.delay` defines plugin delays (in ms). All should be strictly positive. + +`delay.async` is a delay between forcing asynchronous behavior. This usually +means making screen redraws and utilizing |MiniPick.poke_is_picker_active()| +(for example, to stop current matching if query has updated). +Smaller values give smoother user experience at the cost of more computations. + +`delay.busy` is a delay between when some computation starts and showing +visual feedback about it by making window border to have `MiniPickBorderBusy` +highlight group. +Smaller values will give feedback faster at the cost of feeling like flicker. + +# Mappings ~ + +`config.mappings` defines keys for special actions to be triggered after certain +keys. See |MiniPick-actions| for more information. + +# Options ~ + +`config.options` contains some general purpose options. + +`options.content_from_bottom` is a boolean indicating whether content should be +shown from bottom to top. That means that best matches will be shown at +the bottom. Note: for better experience use Neovim>=0.10, which has floating +window footer capability. Default: `false`. + +`options.use_cache` is a boolean indicating whether match results should be +cached per prompt (i.e. concatenated query). This results into faster response +on repeated prompts (like when deleting query entries) at the cost of using +more memory. Default: `false`. + +# Source ~ + +`config.source` defines fallbacks for source specification. For example, this +can be used to change default `match` to use different implementation or `show` +to not show icons for some |MiniPick.builtin| pickers (see |MiniPick-examples|). +See |MiniPick-source| for more information. + +# Window ~ + +`config.window` contains window specific configurations. + +`window.config` defines a (parts of) default floating window config for the main +picker window. This can be either a table overriding some parts or a callable +returning such table. See |MiniPick-examples| for some examples. + +------------------------------------------------------------------------------ + *MiniPick.start()* + `MiniPick.start`({opts}) +Start picker + +Notes: +- If there is currently an active picker, it is properly stopped and new one + is started "soon" in the main event-loop (see |vim.schedule()|). +- Current window at the moment of this function call is treated as "target". + See |MiniPick.get_picker_state()| and |MiniPick.set_picker_target_window()|. + +Parameters~ +{opts} `(table|nil)` Options. Should have same structure as |MiniPick.config|. + Default values are inferred from there. + Usually should have proper |MiniPick-source.items| defined. + +Return~ +`(any)` Item which was current when picker is stopped; `nil` if aborted. + +------------------------------------------------------------------------------ + *MiniPick.stop()* + `MiniPick.stop`() +Stop active picker + +------------------------------------------------------------------------------ + *MiniPick.refresh()* + `MiniPick.refresh`() +Refresh active picker + +------------------------------------------------------------------------------ + *MiniPick.default_match()* + `MiniPick.default_match`({stritems}, {inds}, {query}) +Default match + +Filter target stritems to contain query and sort from best to worst matches. + +Implements default value for |MiniPick-source.match|. + +By default (if no special modes apply) it does the following fuzzy matching: + +- Stritem contains query if it contains all its elements verbatim in the same + order (possibly with gaps, i.e. not strictly one after another). + Note: empty query and empty string element is contained in any string. + +- Sorting is done with the following ordering (same as in |mini.fuzzy|): + - The smaller the match width (end column minus start column) the better. + - Among same match width, the smaller start column the better. + - Among same match width and start column, preserve original order. + +Notes: +- Most common interactive usage results into `query` containing one typed + character per element. + +# Special modes ~ + +- Forced modes: + - Query starts with "*": match the rest fuzzy (without other modes). + - Query starts with "'": match the rest exactly (without gaps). + +- Place modes: + - Query starts with '^': match the rest exactly at start. + - Query ends with '$': match the rest exactly at end. + - Both modes can be used simultaneously. + +- Grouped: query contains at least one whitespace element. Output is computed + as if query is split at whitespace indexes with concatenation between them. + +Precedence of modes: + "forced exact" = "forced fuzzy" > "place start/end" > "grouped" > "default" + +# Examples ~ + +Assuming `stritems` are `{ '_abc', 'a_bc', 'ab_c', 'abc_' }`, here are some +example matches based on prompt (concatenated query): > + + | Prompt | Matches | + |--------|------------------------| + | abc | All | + | *abc | All | + | | | + | 'abc | abc_, _abc | + | *'abc | None (no "'" in items) | + | | | + | ^abc | abc_ | + | *^abc | None (no "^" in items) | + | | | + | abc$ | _abc | + | *abc$ | None (no "$" in items) | + | | | + | ab c | abc_, _abc, ab_c | + | *ab c | None (no " " in items) | + +Having query `{ 'ab', 'c' }` is the same as "ab c" prompt. + +You can have a feel of how this works with this command: > + + MiniPick.start({ source = { items = { '_abc', 'a_bc', 'ab_c', 'abc_' } } }) + +Parameters~ +{stritems} `(table)` Array of all stritems. +{inds} `(table)` Array of `stritems` indexes to match. All of them should point + at string elements of `stritems`. No check is done for performance reasons. +{query} `(table)` Array of strings. + +Return~ +`(table|nil)` Depending of whether there is an active picker: + - If yes, `nil` is returned with |MiniPick.set_picker_match_inds()| used later. + - If no, array of `stritems` indexes matching the `query` (from best to worst). + +------------------------------------------------------------------------------ + *MiniPick.default_show()* + `MiniPick.default_show`({buf_id}, {items}, {query}, {opts}) +Default show + +Show items in a buffer and highlight parts that actually match query (assuming +match is done with |MiniPick.default_match()|). Lines are computed based on +the |MiniPick-source.items-stritems|. + +Implements default value for |MiniPick-source.show|. + +Uses the following highlight groups (see |MiniPick| for their description): + +* `MiniPickIconDirectory` +* `MiniPickIconFile` +* `MiniPickMatchCurrent` +* `MiniPickMatchMarked` +* `MiniPickMatchRanges` + +Parameters~ +{buf_id} `(number)` Identifier of target buffer. +{items} `(table)` Array of items to show. +{query} `(table)` Array of strings representing query. +{opts} `(table|nil)` Options. Possible fields: + - `(boolean)` - whether to show icons for entries recognized as + valid actually present paths on disk (see |MiniPick-source.items-common|), + empty space otherwise. + Default: `false`. Note: |MiniPick.builtin| pickers showing file/directory + paths use `true` by default. + +------------------------------------------------------------------------------ + *MiniPick.default_preview()* + `MiniPick.default_preview`({buf_id}, {item}, {opts}) +Default preview + +Preview item. Logic follows the rules in |MiniPick-source.items-common|: +- File and buffer are shown at the start. +- Directory has its content listed. +- Line/position/region in file or buffer is shown at start. +- Others are shown directly with |vim.inspect()|. + +Implements default value for |MiniPick-source.preview|. + +Uses the following highlight groups (see |MiniPick| for their description): + +* `MiniPickPreviewLine` +* `MiniPickPreviewRegion` + +Parameters~ +{buf_id} `(number)` Identifier of target buffer. +{item} `(any)` Item to preview. +{opts} `(table|nil)` Options. Possible values: + - `(number)` - number of lines to load past target position + when reading from disk. Useful to explore context. Default: 'lines' twice. + - `(string)` - where in the window to show item position. + One of "top", "center", "bottom". Default: "top". + +------------------------------------------------------------------------------ + *MiniPick.default_choose()* + `MiniPick.default_choose`({item}) +Default choose + +Choose item. Logic follows the rules in |MiniPick-source.items-common|: +- File and directory are called with |:edit| in the target window, possibly + followed by setting cursor at the start of line/position/region. +- Buffer is set as current in target window. +- Others have the output of |vim.inspect()| printed in Command line. + +Implements default value for |MiniPick-source.choose|. + +Parameters~ +{item} `(any)` Item to choose. + +------------------------------------------------------------------------------ + *MiniPick.default_choose_marked()* + `MiniPick.default_choose_marked`({items}, {opts}) +Default choose marked items + +Choose marked items. Logic follows the rules in |MiniPick-source.items-common|: +- If among items there is at least one file or buffer, quickfix list is opened + with all file or buffer lines/positions/regions. +- Otherwise, picker's `source.choose` is called on the first item. + +Implements default value for |MiniPick-source.choose_marked|. + +Parameters~ +{items} `(table)` Array of items to choose. +{opts} Options. Possible fields: + - `(string)` - which type of list to open. One of "quickfix" + or "location". Default: "quickfix". + +------------------------------------------------------------------------------ + *MiniPick.ui_select()* + `MiniPick.ui_select`({items}, {opts}, {on_choice}) +Select rewrite + +Function which can be used to directly override |vim.ui.select()| to use +'mini.pick' for any "select" type of tasks. + +Implements the required by `vim.ui.select()` signature. Plus allows extra +`opts.preview_item` to serve as preview. + +------------------------------------------------------------------------------ + *MiniPick.builtin* + `MiniPick.builtin` +Table with built-in pickers + +------------------------------------------------------------------------------ + *MiniPick.builtin.files()* + `MiniPick.builtin.files`({local_opts}, {opts}) +Pick from files + +Lists all files: recursively in all subdirectories including hidden files. +Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +`rg`, `fd`, `git`. If none is present, uses fallback which utilizes |vim.fs.dir()|. + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Possible fields: + - `(string)` - which tool to use. One of "rg", "fd", "git", "fallback". + Default: whichever tool is present, trying in that same order. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.grep()* + `MiniPick.builtin.grep`({local_opts}, {opts}) +Pick from pattern matches + +Lists all pattern matches: recursively in all subdirectories including +hidden files. +Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +`rg`, `git`. If none is present, uses fallback which utilizes |vim.fs.dir()| and +Lua pattern matches (NOT recommended in large directories). + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Possible fields: + - `(string)` - which tool to use. One of "rg", "git", "fallback". + Default: whichever tool is present, trying in that same order. + - `(string)` - string pattern to search. If not given, asks user + interactively with |input()|. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.grep_live()* + `MiniPick.builtin.grep_live`({local_opts}, {opts}) +Pick from pattern matches with live feedback + +Perform pattern matching treating prompt as pattern. Gives live feedback on +which matches are found. Use |MiniPick-actions-refine| to revert to regular +matching. +Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +`rg`, `git`. If none is present, error is thrown (for performance reasons). + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Possible fields: + - `(string)` - which tool to use. One of "rg", "git". + Default: whichever tool is present, trying in that same order. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.help()* + `MiniPick.builtin.help`({local_opts}, {opts}) +Pick from help tags + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Not used at the moment. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.buffers()* + `MiniPick.builtin.buffers`({local_opts}, {opts}) +Pick from buffers + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Possible fields: + - `(boolean)` - whether to include current buffer in + the output. Default: `true`. + - `(boolean)` - whether to include |unlisted-buffer|s in + the output. Default: `false`. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.cli()* + `MiniPick.builtin.cli`({local_opts}, {opts}) +Pick from CLI output + +Executes command line tool and constructs items based on its output. +Uses |MiniPick.set_picker_items_from_cli()|. + +Example: `MiniPick.builtin.cli({ command = { 'echo', 'a\nb\nc' } })` + +Parameters~ +{local_opts} `(table|nil)` Options defining behavior of this particular picker. + Possible fields: + - `(table)` - forwarded to `set_picker_items_from_cli()`. + - `(function)` - forwarded to `set_picker_items_from_cli()`. + - `(table)` - forwarded to `set_picker_items_from_cli()`. + Note: if `cwd` field is absent, it is inferred from |MiniPick-source.cwd|. +{opts} `(table|nil)` Options forwarded to |MiniPick.start()|. + +------------------------------------------------------------------------------ + *MiniPick.builtin.resume()* + `MiniPick.builtin.resume`() +Resume latest picker + +------------------------------------------------------------------------------ + *MiniPick.registry* + `MiniPick.registry` +Picker registry + +Place for users and extensions to manage pickers with their commonly used +global options. By default contains all |MiniPick.builtin| entries. + +Serves as a source for |:Pick| command. + +Customization examples: > + + -- Adding custom picker + require('mini.pick').registry.arglist = function() + local source = { items = vim.fn.argv, name = 'Arglist' } + return MiniPick.start({ source = source }) + end + + -- Make `:Pick files` accept `cwd` + MiniPick.registry.files = function(local_opts) + local opts = { source = { cwd = local_opts.cwd } } + local_opts.cwd = nil + return MiniPick.builtin.files(local_opts, opts) + end + +------------------------------------------------------------------------------ + *MiniPick.get_picker_items()* + `MiniPick.get_picker_items`() +Get items of active picker + +Return~ +`(table|nil)` Picker items or `nil` if no active picker. + +See also~ +|MiniPick.set_picker_items()| and |MiniPick.set_picker_items_from_cli()| + +------------------------------------------------------------------------------ + *MiniPick.get_picker_stritems()* + `MiniPick.get_picker_stritems`() +Get stritems of active picker + +Return~ +`(table|nil)` Picker stritems (|MiniPick-source.items-stritems|) or `nil` if + no active picker. + +See also~ +|MiniPick.set_picker_items()| and |MiniPick.set_picker_items_from_cli()| + +------------------------------------------------------------------------------ + *MiniPick.get_picker_matches()* + `MiniPick.get_picker_matches`() +Get matches of active picker + +Return~ +`(table|nil)` Picker matches or `nil` if no active picker. Matches is a table + with the following fields: + - `(table|nil)` - all currently matched items. + - `(table|nil)` - indexes of all currently matched items. + - `(any)` - current matched item. + - `(number|nil)` - index of current matched item. + - `(table|nil)` - marked items. + - `(table|nil)` - indexes of marked items. + +See also~ +|MiniPick.set_picker_match_inds()| + +------------------------------------------------------------------------------ + *MiniPick.get_picker_opts()* + `MiniPick.get_picker_opts`() +Get config of active picker + +Return~ +`(table|nil)` Picker config (`start()`'s input `opts` table) or `nil` if + no active picker. + +See also~ +|MiniPick.set_picker_opts()| + +------------------------------------------------------------------------------ + *MiniPick.get_picker_state()* + `MiniPick.get_picker_state`() +Get state data of active picker + +Return~ +`(table|nil)` Table with picker state data or `nil` if no active picker. + State data is a table with the following fields: + - `(table)` - table with `main`, `preview`, `info` fields representing + buffer identifier (or `nil`) for corresponding view. + - `(table)` - table with `main` and `target` fields representing + window identifiers for main and target windows. + - `(number)` - caret column. + - `(boolean)` - whether picker is busy with computations. + +See also~ +|MiniPick.set_picker_target_window()| + +------------------------------------------------------------------------------ + *MiniPick.get_picker_query()* + `MiniPick.get_picker_query`() +Get query of active picker + +Return~ +`(table|nil)` Array of picker query or `nil` if no active picker. + +See also~ +|MiniPick.set_picker_query()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_items()* + `MiniPick.set_picker_items`({items}, {opts}) +Set items for active picker + +Note: sets items asynchronously in non-blocking fashion. + +Parameters~ +{items} `(table)` Array of items. +{opts} `(table|nil)` Options. Possible fields: + - `(boolean)` - whether to perform match after setting items. + Default: `true`. + - `(number|nil)` - value of querytick (|MiniPick.get_querytick()|) + to periodically check against when setting items. If checked querytick + differs from supplied, no items are set. + +See also~ +|MiniPick.get_picker_items()| and |MiniPick.get_picker_stritems()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_items_from_cli()* + `MiniPick.set_picker_items_from_cli`({command}, {opts}) +Set items for active picker based on CLI output + +Asynchronously executes `command` and sets items to its postprocessed output. + +Example: > + local items = vim.schedule_wrap(function() + MiniPick.set_picker_items_from_cli({ 'echo', 'a\nb\nc' }) + end) + MiniPick.start({ source = { items = items, name = 'Echo abc' } }) + +Parameters~ +{command} `(table)` Array with (at least one) string command parts. +{opts} `(table|nil)` Options. Possible fields: + - `(function)` - callable performing postprocessing of output. + Will be called with array of lines as input, should return array of items. + Default: removes trailing empty lines and uses rest as string items. + - `(table)` - `options` for |uv.spawn|, except `args` and `stdio` fields. + - `(table)` - table forwarded to |MiniPick.set_picker_items()|. + +See also~ +|MiniPick.get_picker_items()| and |MiniPick.get_picker_stritems()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_match_inds()* + `MiniPick.set_picker_match_inds`({match_inds}) +Set match indexes for active picker + +This is intended to be used inside custom asynchronous |MiniPick-source.match| +implementations. See |MiniPick.poke_is_picker_active()| for an example. + +Parameters~ +{match_inds} `(table)` Array of numbers indicating which elements of picker's + stritems match the query. + +See also~ +|MiniPick.get_picker_matches()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_opts()* + `MiniPick.set_picker_opts`({opts}) +Set config for active picker + +Parameters~ +{opts} `(table)` Table overriding initial `opts` input of |MiniPick.start()|. + +See also~ +|MiniPick.get_picker_opts()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_target_window()* + `MiniPick.set_picker_target_window`({win_id}) +Set target window for active picker + +Parameters~ +{win_id} `(number)` Valid window identifier to be used as the new target window. + +See also~ +|MiniPick.get_picker_state()| + +------------------------------------------------------------------------------ + *MiniPick.set_picker_query()* + `MiniPick.set_picker_query`({query}) +Set query for active picker + +Parameters~ +{query} `(table)` Array of strings to be set as the new picker query. + +See also~ +|MiniPick.get_picker_query()| + +------------------------------------------------------------------------------ + *MiniPick.get_querytick()* + `MiniPick.get_querytick`() +Get query tick + +Query tick is a unique query identifier. Intended to be used to detect user +activity during and between |MiniPick.start()| calls for efficient non-blocking +functionality. Updates after any query change, picker start and stop. + +See |MiniPick.poke_is_picker_active()| for usage example. + +Return~ +`(number)` Query tick. + +------------------------------------------------------------------------------ + *MiniPick.is_picker_active()* + `MiniPick.is_picker_active`() +Check if there is an active picker + +Return~ +`(boolean)` Whether there is currently an active picker. + +See also~ +|MiniPick.poke_is_picker_active()| + +------------------------------------------------------------------------------ + *MiniPick.poke_is_picker_active()* + `MiniPick.poke_is_picker_active`() +Poke if picker is active + +Intended to be used for non-blocking implementation of source methods. +Returns an output of |MiniPick.is_picker_active()|, but depending on +whether there is a coroutine running: +- If no, return it immediately. +- If yes, return it after `coroutine.yield()` with `coroutine.resume()` + called "soon" by the main event-loop (see |vim.schedule()|). + +Example of non-blocking exact `match` (as demo; can be optimized further): > + + local match_nonblock = function(match_inds, stritems, query) + local prompt, querytick = table.concat(query), MiniPick.get_querytick() + local f = function() + local res = {} + for _, ind in ipairs(match_inds) do + local should_stop = not MiniPick.poke_is_picker_active() or + MiniPick.get_querytick() ~= querytick + if should_stop then return end + + if stritems[ind]:find(prompt) ~= nil then table.insert(res, ind) end + end + + MiniPick.set_picker_match_inds(res) + end + + coroutine.resume(coroutine.create(f)) + end + +Return~ +`(boolean)` Whether there is an active picker. + +See also~ +|MiniPick.is_picker_active()| + + + vim:tw=78:ts=8:noet:ft=help:norl: \ No newline at end of file diff --git a/doc/mini.txt b/doc/mini.txt index ac803548..4877276d 100644 --- a/doc/mini.txt +++ b/doc/mini.txt @@ -38,6 +38,7 @@ Table of contents: Move any selection in any direction ............................ |mini.move| Text edit operators ....................................... |mini.operators| Autopairs ..................................................... |mini.pairs| + Pick anything .................................................. |mini.pick| Session management ......................................... |mini.sessions| Split and join arguments .................................. |mini.splitjoin| Start screen ................................................ |mini.starter| @@ -221,6 +222,11 @@ Table of contents: - |MiniPairs| - autopairs plugin which has minimal defaults and functionality to do per-key expression mappings. +- |MiniPick| - general purpose interactive non-blocking picker with + toggleable preview. Has fast default matching with fuzzy/exact/grouped + modes. Provides most used built-in pickers for files, pattern matches, + buffers, etc. + - |MiniSessions| - session management (read, write, delete) which works using |mksession|. Implements both global (from configured directory) and local (from current directory) sessions. diff --git a/lua/mini/init.lua b/lua/mini/init.lua index 0c1ea3d4..791103e2 100644 --- a/lua/mini/init.lua +++ b/lua/mini/init.lua @@ -38,6 +38,7 @@ --- Move any selection in any direction ............................ |mini.move| --- Text edit operators ....................................... |mini.operators| --- Autopairs ..................................................... |mini.pairs| +--- Pick anything .................................................. |mini.pick| --- Session management ......................................... |mini.sessions| --- Split and join arguments .................................. |mini.splitjoin| --- Start screen ................................................ |mini.starter| @@ -221,6 +222,11 @@ --- - |MiniPairs| - autopairs plugin which has minimal defaults and --- functionality to do per-key expression mappings. --- +--- - |MiniPick| - general purpose interactive non-blocking picker with +--- toggleable preview. Has fast default matching with fuzzy/exact/grouped +--- modes. Provides most used built-in pickers for files, pattern matches, +--- buffers, etc. +--- --- - |MiniSessions| - session management (read, write, delete) which works --- using |mksession|. Implements both global (from configured directory) and --- local (from current directory) sessions. diff --git a/lua/mini/pick.lua b/lua/mini/pick.lua new file mode 100644 index 00000000..ccbb0eca --- /dev/null +++ b/lua/mini/pick.lua @@ -0,0 +1,3263 @@ +--- *mini.pick* Pick anything +--- *MiniPick* +--- +--- MIT License Copyright (c) 2023 Evgeni Chasnovski +--- +--- ============================================================================== +--- +--- Features: +--- +--- - Single window general purpose interface for picking element from any array. +--- +--- - On demand toggleable preview and info views. +--- +--- - Interactive query matching (filter+sort) with fast non-blocking default +--- which does fuzzy matching and allows other modes (|MiniPick.default_match()|). +--- +--- - Built-in pickers (see |MiniPick.builtin|): +--- - Files. +--- - Pattern match (for fixed pattern and with live feedback). +--- - Buffers. +--- - Help tags. +--- - CLI output. +--- - Resume latest picker. +--- +--- - |:Pick| command to work with extensible |MiniPick.registry|. +--- +--- - |vim.ui.select()| wrapper (see |MiniPick.ui_select()|). +--- +--- - Rich and customizable built-in |MiniPick-actions| when picker is active: +--- - Manually change currently focused item. +--- - Scroll vertically and horizontally. +--- - Toggle preview or info view. +--- - Mark/unmark items to choose later. +--- - Refine current matches (make them part of a new picker). +--- - And many more. +--- +--- - Minimal yet flexible |MiniPick-source| specification with: +--- - Items (array, callable, or manually set later). +--- - Source name. +--- - Working directory. +--- - Matching algorithm. +--- - Way matches are shown in main window. +--- - Item preview. +--- - "On choice" action for current and marked items. +--- +--- - Custom actions/keys can be configured globally, per buffer, or per picker. +--- +--- - Out of the box support for 'ignorecase' and 'smartcase'. +--- +--- - Match caching to increase responsiveness on repeated prompts. +--- +--- Notes: +--- - Works on all supported versions but using Neovim>=0.9 is recommended. +--- Neovim>=0.10 will give more visual feedback in floating window footer. +--- +--- Sources with more details: +--- - |MiniPick-overview| +--- - |MiniPick-source| +--- - |MiniPick-actions| +--- - |MiniPick-examples| +--- - |MiniPick.builtin| +--- +--- # Dependencies ~ +--- +--- Suggested dependencies (provide extra functionality, will work without them): +--- +--- - Plugin 'nvim-tree/nvim-web-devicons' for filetype icons near the items +--- representing actual paths. If missing, default or no icons will be used. +--- +--- *MiniPick-cli-tools* +--- - CLI tool(s) to power |MiniPick.builtin.files()|, |MiniPick.builtin.grep()|, and +--- |MiniPick.builtin.grep_live()| built-in pickers: +--- - `rg` ('github.com/BurntSushi/ripgrep'; enough for all three; recommended). +--- - `fd` ('github.com/sharkdp/fd'; for `files` only). +--- - `git` ('github.com/git/git'; enough for all three). +--- +--- # Setup ~ +--- +--- This module needs a setup with `require('mini.pick').setup({})` (replace +--- `{}` with your `config` table). It will create global Lua table `MiniPick` +--- which you can use for scripting or manually (with `:lua MiniPick.*`). +--- +--- See |MiniPick.config| for available config settings. +--- +--- You can override runtime config settings locally to buffer inside +--- `vim.b.minioperators_config` which should have same structure as +--- `MiniPick.config`. See |mini.nvim-buffer-local-config| for more details. +--- +--- # Comparisons ~ +--- +--- - 'nvim-telescope/telescope.nvim': +--- - The main inspiration for this module, so there is significant overlap. +--- - Has three (or two) window UI (prompt, matches, preview), while this +--- module combines everything in one window. It allows more straightforward +--- customization for unusual scenarios. +--- - Default match algorithm is somewhat slow, while this module should +--- match relatively lag-free for at least 100K+ items. +--- - Has many built-in pickers, while this module has handful at its core +--- relying on other 'mini.nvim' modules to provide more. +--- +--- - 'ibhagwan/fzf-lua': +--- - Mostly same comparison as with 'nvim-telescope/telescope.nvim'. +--- - Requires 'junegunn/fzf' installed to power fuzzy matching, while this +--- module provides built-in Lua matching. +--- +--- # Highlight groups ~ +--- +--- * `MiniPickBorder` - window border. +--- * `MiniPickBorderBusy` - window border while picker is busy processing. +--- * `MiniPickBorderText` - non-prompt on border. +--- * `MiniPickIconDirectory` - default icon for directory. +--- * `MiniPickIconFile` - default icon for file. +--- * `MiniPickHeader` - headers in info buffer and previews. +--- * `MiniPickMatchCurrent` - current matched item. +--- * `MiniPickMatchMarked` - marked matched items. +--- * `MiniPickMatchRanges` - ranges matching query elements. +--- * `MiniPickNormal` - basic foreground/background highlighting. +--- * `MiniPickPreviewLine` - target line in preview. +--- * `MiniPickPreviewRegion` - target region in preview. +--- * `MiniPickPrompt` - prompt. +--- +--- To change any highlight group, modify it directly with |:highlight|. + +--- Events ~ +--- +--- To allow user customization and integration of external tools, certain |User| +--- autocommand events are triggered under common circumstances: +--- +--- - `MiniPickStart` - just after picker has started. +--- - `MiniPickStop` - just before picker is stopped. +---@tag MiniPick-events + +--- # Overview ~ +--- +--- General idea is to take array of objects, display them with interactive +--- filter/sort/navigate/preview, and allow to choose one or more items. +--- +--- ## How to start a picker ~ +--- +--- - Use |MiniPick.start()| with `opts.source` defining |MiniPick-source|. +--- Example: `MiniPick.start({ source = { items = vim.fn.readdir('.') } })` +--- +--- - Use any of |MiniPick.builtin| pickers directly. +--- Example: `MiniPick.builtin.files({ tool = 'git' })` +--- +--- - Use |:Pick| command which uses customizable pickers from |MiniPick.registry|. +--- Example: `:Pick files tool=git` +--- +--- ## User interface ~ +--- +--- UI consists from a single window capable of displaying three different views: +--- - "Main" - where current query matches are shown. +--- - "Preview" - preview of current item (toggle with ``). +--- - "Info" - general info about picker and its state (toggle with ``). +--- +--- Current prompt is displayed (in Neovim>=0.9) at the top left of the window +--- border with vertical line indicating caret (current input position). +--- +--- Bottom part of window border displays (in Neovim>=0.10) extra visual feedback: +--- - Left part is a picker name. +--- - Right part contains information in the format > +--- | | / +--- +--- When picker is busy (like if there are no items yet set or matching is active) +--- window border changes color to be `MiniPickBorderBusy` after `config.delay.busy` +--- milliseconds of idle time. +--- +--- ## Life cycle ~ +--- +--- - Type characters to filter and sort matches. It uses |MiniPick.default_match()| +--- with `query` being an array of pressed characters. +--- Overview of how it matches: +--- - If query starts with `'`, the match is exact. +--- - If query starts with `^`, the match is exact at start. +--- - If query starts with `$`, the match is exact at end. +--- - If query starts with `*`, the match is forced to be fuzzy. +--- - Otherwise match is fuzzy. +--- - Sorting is done to first minimize match width and then match start. +--- Nothing more: no favoring certain places in string, etc. +--- +--- - Type special keys to perform |MiniPick-actions|. Here are some basic ones: +--- - `` / `` moves down; `` / `` moves up. +--- - `` / `` moves prompt caret left / right. +--- - `` toggles information window with all available mappings. +--- - `` toggles preview. +--- - `` / `` toggles current / all item(s) as (un)marked. +--- - `` / `` makes all matches or marked items as new picker. +--- - `` / `` chooses current/marked item(s). +--- - `` / `` stops picker. +--- +--- ## Implementation details ~ +--- +--- - Any picker is non-blocking but waits to return the chosen item. Example: +--- `file = MiniPick.builtin.files()` allows other actions to be executed when +--- picker is shown while still assigning `file` with value of the chosen item. +---@tag MiniPick-overview + +--- Source is defined as a `source` field inside one of (in increasing priority): +--- - |MiniPick.config| - has global effect. +--- - |vim.b.minipick_config| - has buffer-local effect. +--- - `opts.source` in picker call - has effect for that particular call. +--- +--- Example of source to choose from |arglist|: > +--- { items = vim.fn.argv, name = 'Arglist' } +--- < +--- +--- Note: this is mostly useful for writing pickers. Can safely skip if you +--- want to just use provided pickers. +--- +--- *MiniPick-source.items* +--- # Items ~ +--- +--- `source.items` defines items to choose from. It should be one of the following: +--- - Array of objects which can have different types. Any type is allowed. +--- - `nil`. Picker waits for explicit |MiniPick.set_picker_items()| call. +--- - Callable returning any of the previous types. Will be called once on start. +--- +--- *MiniPick-source.items-stritems* +--- Matching is done for items array based on the string representation of its +--- elements (here called "stritems"). For single item it is computed as follows: +--- - Callable is called once with output used in next steps. +--- - String item is used as is. +--- - String field of table item is used (if present). +--- - Use output of |vim.inspect()|. +--- +--- Example: > +--- +--- items = { 'aaa.txt', { text = 'bbb' }, function() return 'ccc' end } +--- -- corresponding stritems are { 'aaa.txt', 'bbb', 'ccc' } +--- +--- Default value is `nil`, assuming it always be supplied by the caller. +--- +--- *MiniPick-source.items-common* +--- There are some recommendations for common item types in order for them to work +--- out of the box with |MiniPick.default_show()|, |MiniPick.default_preview()|, +--- |MiniPick.default_choose()|, |MiniPick.default_choose_marked()|: +--- +--- - Path (file or directory). Use string or `path` field of a table. Path can +--- be either absolute or relative to the `source.cwd`. +--- Examples: `'aaa.txt'`, `{ path = 'aaa.txt' }` +--- +--- - Buffer. Use buffer id as number, string, or `bufnr` / `buf_id` / `buf` +--- field of a table (any name is allowed). +--- Examples: `1`, `'1'`, `{ bufnr = 1 }`, `{ buf_id = 1 }`, `{ buf = 1 }` +--- +--- - Line in file or buffer. Use table representation with `lnum` field with line +--- number (starting from 1). Files can use string in ":" format. +--- Examples: > +--- { path = 'aaa.txt', lnum = 2 }, 'aaa.txt:2', { path = 'aaa.txt:2' }, +--- { bufnr = 1, lnum = 3 } +--- +--- - Position in file or buffer. Use table representation with `lnum` and `col` +--- fields with line and column numbers (starting from 1). Files can use string +--- in "::" format. +--- Examples: > +--- { path = 'aaa.txt', lnum = 2, col = 3 }, 'aaa.txt:2:3', +--- { path = 'aaa.txt:2:3' }, { bufnr = 1, lnum = 3, col = 4 } +--- +--- - Region in file or buffer. Use table representation with `lnum`, `col`, +--- `end_lnum`, `end_col` fields for start and end line/column. All numbers +--- start from 1, end line is inclusive, end column is exclusive. +--- This naming is similar to |getqflist()| and |diagnostic-structure|. +--- Examples: > +--- { path = 'aaa.txt', lnum = 2, col = 3, end_lnum = 4, end_col = 5 }, +--- { bufnr = 1, lnum = 3, col = 4, end_lnum = 5, end_col = 6 } +--- +--- Note: all table items will benefit from having `text` field for better matching. +--- +--- *MiniPick-source.name* +--- # Name ~ +--- +--- `source.name` defines the name of the picker to be used for visual feedback. +--- +--- Default value is "". +--- +--- *MiniPick-source.cwd* +--- # Current working directory ~ +--- +--- `source.cwd` is a string defining the current working directory in which +--- picker operates. It should point to a valid actually present directory path. +--- This is a part of source to allow persistent way to use relative paths, +--- i.e. not depend on current directory being constant after picker start. +--- It also makes the |MiniPick.builtin.resume()| picker more robust. +--- +--- Default value is |current-directory|. +--- +--- *MiniPick-source.match* +--- # Match ~ +--- +--- `source.match` is a callable defining how stritems +--- (see |MiniPick-source.items-stritems|) are matched (filetered and sorted) based +--- on the query. +--- +--- It will be called with the following arguments: +--- - `stritems` - all available stritems for current picker. +--- - `inds` - array of `stritems` indexes usually pointing at current matches. +--- It does point to current matches in the case of interactively appending +--- character at the end of the query. It assumes that matches for such bigger +--- query is a subset of previous matches (implementation can ignore it). +--- This can be utilized to increase performance by checking fewer stritems. +--- - `query` - array of strings. Usually (like is common case of user interactively +--- typing query) each string represents one character. However, any strings are +--- allowed, as query can be set with |MiniPick.set_picker_query()|. +--- +--- It should either return array of match indexes for stritems elements matching +--- the query (synchronous) or explicitly use |MiniPick.set_picker_match_inds()| +--- to set them (may be asynchronous). +--- +--- Notes: +--- - The result can be any array of `stritems` indexes, i.e. not necessarily +--- a subset of input `inds`. +--- +--- - Both `stritems` and `query` depend on values of 'ignorecase' and 'smartcase'. +--- If query shows "ignore case" properties (only 'ignorecase' is set or both +--- 'ignorecase' / 'smartcase' are set and query has only lowercase characters), +--- then `stritems` and `query` will have only lowercase characters. +--- This allows automatic support for case insensitive matching while being +--- faster and having simpler match function implementation. +--- +--- - Writing custom `source.match` usually means also changing |MiniPick-source.show| +--- because it is used to highlight stritems parts actually matching the query. +--- +--- Example of simple "exact" `match()` preserving initial order: > +--- +--- local match_exact = function(stritems, inds, query) +--- local prompt_pattern = vim.pesc(table.concat(query)) +--- local f = function(i) return stritems[i]:find(prompt_pattern) ~= nil end +--- return vim.tbl_filter(f, inds) +--- end +--- < +--- For non-blocking version see |MiniPick.poke_is_picker_active()|. +--- +--- Default value is |MiniPick.default_match()|. +--- +--- *MiniPick-source.show* +--- # Show ~ +--- +--- `source.show` is a callable defining how matched items are shown in the window. +--- +--- It will be called with the following arguments: +--- - `buf_id` - identifier of the target buffer. +--- - `items_to_show` - array of actual items to be shown in `buf_id`. This is +--- a subset of currently matched items computed to fit in current window view. +--- - `query` - array of strings. Same as in `source.match`. +--- +--- It should update buffer `buf_id` to visually represent `items_to_show` +--- __one item per line starting from line one__ (it shouldn't depend on +--- `options.content_from_bottom`). This also includes possible visualization +--- of which parts of stritem actually matched query. +--- +--- Example (assuming string items; without highlighting): > +--- +--- local show_prepend = function(buf_id, items_arr, query) +--- local lines = vim.tbl_map(function(x) return 'Item: ' .. x end, items_arr) +--- vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) +--- end +--- +--- Default value is |MiniPick.default_show()|. +--- +--- *MiniPick-source.preview* +--- # Preview ~ +--- +--- `source.preview` is a callable defining how item preview is done. +--- +--- It will be called with the following arguments: +--- - `buf_id` - identifier of the target buffer. Note: for every separate instance +--- of item previewing new scratch buffer is be created. +--- - `item` - item to preview. +--- +--- It should update buffer `buf_id` to visually represent `item`. +--- +--- Example: > +--- +--- local preview_inspect = function(buf_id, item) +--- local lines = vim.split(vim.inspect(item), '\n') +--- vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) +--- end +--- +--- Default value is |MiniPick.default_preview()|. +--- +--- *MiniPick-source.choose* +--- # Choose an item ~ +--- +--- `source.choose` is a callable defining what to do when an item is chosen. +--- +--- It will be called with the following arguments: +--- - `item` - chosen item. Always non-`nil`. +--- +--- It should perform any intended "choose" action for an item and return +--- a value indicating whether picker should continue (i.e. not stop): +--- `nil` and `false` will stop picker, other values will continue. +--- +--- Notes: +--- - It is called when picker window is still current. Use `windows.target` value +--- from |MiniPick.get_picker_state()| output to do something with target window. +--- +--- Example: > +--- +--- local choose_file_continue = function(item) +--- if vim.fn.filereadable(item) == 0 then return end +--- vim.api.nvim_win_call( +--- MiniPick.get_picker_state().windows.main, +--- function() vim.cmd('edit ' .. item) end +--- ) +--- return true +--- end +--- +--- Default value is |MiniPick.default_choose()|. +--- +--- *MiniPick-source.choose_marked* +--- # Choose marked items ~ +--- +--- `source.choose_marked` is a callable defining what to do when marked items +--- (see |MiniPick-actions-mark|) are chosen. Serves as a companion to +--- `source.choose` which can choose several items. +--- +--- It will be called with the following arguments: +--- - `items_marked` - array of marked items. Can be empty. +--- +--- It should perform any intended "choose" action for several items and return +--- a value indicating whether picker should continue (i.e. not stop): +--- `nil` and `false` will stop picker, other values will continue. +--- +--- Notes: +--- - It is called when picker window is still current. Use `windows.target` value +--- from |MiniPick.get_picker_state()| output to do something with target window. +--- +--- Example: > +--- +--- local choose_marked_print = function(items) print(vim.inspect(items)) end +--- +--- Default value is |MiniPick.default_choose_marked()|. +---@tag MiniPick-source + +--- When picker is active, `mappings` table defines a set of special keys which when +--- pressed will execute certain actions. Those can be of two types: +--- - Built-in: actions present in default `config.mappings`. Can be only overridden +--- with a different key. +--- - Custom: user defined actions. Should be a table with `char` and `func` fields. +--- +--- +--- # Built-in ~ +--- *MiniPick-actions-caret* +--- ## Caret ~ +--- +--- User can add character not only at query end, but more generally at caret. +--- +--- - `mappings.caret_left` - move caret to left. +--- - `mappings.caret_right` - move caret to right. +--- +--- *MiniPick-actions-choose* +--- ## Choose ~ +--- +--- Choose is a fundamental action that actually implements the intent of +--- calling a picker, i.e. pick an item. +--- +--- - `mappings.choose` - choose as is, i.e. apply `source.choose` for current item. +--- - `mappings.choose_in_split` - make horizontal split at target window, update +--- target window to the new split, and choose. +--- - `mappings.choose_in_tabpage` - same as `choose_in_split`, but create tabpage. +--- - `mappings.choose_in_vsplit` - same as `choose_in_split`, but split vertically. +--- - `mappings.choose_marked` - choose marked items as is, i.e. +--- apply `source.choose_marked` at current marked items. +--- +--- *MiniPick-actions-delete* +--- ## Delete ~ +--- +--- Delete actions are for deleting elements from query. +--- +--- - `mappings.delete_char` - delete one character to the left. +--- - `mappings.delete_char_right` - delete one character to the right. +--- - `mappings.delete_left` - delete everything to the left (like |i_CTRL-U|). +--- - `mappings.delete_word` - delete word to the left (like |i_CTRL-W|). +--- +--- *MiniPick-actions-mark* +--- ## Mark ~ +--- +--- Marking is an action of adding certain items to a separate list which then can +--- be chosen with `mappings.choose_marked` (for example, sent to quickfix list). +--- This is a companion to a regular choosing which can pick only one item. +--- +--- - `mappings.mark` - toggle marked/unmarked state of current item. +--- - `mappings.mark_all` - toggle marked/unmarked state (mark all if not all +--- marked; unmark all otherwise) of all currently matched items. +--- +--- Notes: +--- - Marks persist across queries and matches. For example, user can make a query +--- with marking all matches several times and marked items from all queries +--- will be preserved. +--- +--- *MiniPick-actions-move* +--- ## Move ~ +--- +--- Move is a fundamental action of changing which item is current. +--- +--- - `mappings.move_down` - change focus to the item below. +--- - `mappings.move_start` change focus to the first currently matched item +--- - `mappings.move_up` - change focus to the item above. +--- +--- Notes: +--- - Up and down wrap around edges: `move_down` on last item moves to first, +--- `move_up` on first moves to last. +--- - Moving when preview or info view is shown updates the view with new item. +--- - These also work with non-overridable alternatives: +--- - `` moves down. +--- - `` moves to first matched. +--- - `` moves up. +--- +--- *MiniPick-actions-paste* +--- ## Paste ~ +--- +--- Paste is an action to paste content of |registers| at caret. +--- +--- - `mappings.paste` - paste from register defined by the next key press. +--- +--- Notes: +--- - Does not support expression register `=`. +--- +--- *MiniPick-actions-refine* +--- ## Refine ~ +--- +--- Refine is an action that primarily executes the following: +--- - Takes certain items and makes them be all items (in order they are present). +--- - Resets query. +--- - Updates `source.match` to be the one from config. +--- +--- - `mappings.refine` - refine currently matched items. +--- - `mappings.refin_marked` - refine currently marked items. +--- +--- This action is useful in at least two cases: +--- - Perform consecutive "narrowing" queries. Example: to get items that contain +--- both "hello" and "world" exact matches (in no particular order) with default +--- matching, type "'hello" (notice "'" at the start) followed by `` and +--- another "'world". +--- - Reset `match` to default. Particularly useful in |MiniPick.builtin.grep_live()|. +--- +--- *MiniPick-actions-scroll* +--- ## Scroll ~ +--- +--- Scroll is an action to either move current item focus further than to the +--- neighbor item or adjust window view to see more information. +--- +--- - `mappings.scroll_down` - when matches are shown, go down by the amount of +--- visible matches. In preview and info view - scroll down as with |CTRL-F|. +--- - `mappings.scroll_left` - scroll left as with |zH|. +--- - `mappings.scroll_right` - scroll right as with |zL|. +--- - `mappings.scroll_up` - when matches are shown, go up by the amount of +--- visible matches. In preview and info view - scroll up as with |CTRL-B|. +--- +--- *MiniPick-actions-stop* +--- ## Stop ~ +--- +--- `mappings.stop` stops the picker. also always stops the picker. +--- +--- +--- *MiniPick-actions-toggle* +--- ## Toggle ~ +--- +--- Toggle action is a way to change view: show if target is not shown, reset to +--- main view otherwise. +--- +--- - `mappings.toggle_info` - toggle info view. +--- - `mappings.toggle_preview` - toggle preview. +--- +--- Note: +--- - Updating query in any way resets window view to show matches. +--- - Moving current item focus keeps preview or info view with updated item. +--- +--- *MiniPick-actions-custom* +--- # Custom ~ +--- +--- Along with built-in actions, users can define custom actions. This can be +--- done by supplying custom elements to `mappings` table. The field defines action +--- name (used to infer an action description in info view). The value is a table +--- with the following fields: +--- - `(string)` - single character acting as action trigger. +--- - `(function)` - callable to be executed without arguments after +--- user presses . +--- +--- Example of `execute` custom mapping: > +--- +--- execute = { +--- char = '', +--- func = function() vim.cmd(vim.fn.input('Execute: ')) end, +--- } +---@tag MiniPick-actions + +--- Common configuration examples ~ +--- +--- - Disable icons in |MiniPick.builtin| pickers related to paths: > +--- +--- local pick = require('mini.pick') +--- pick.setup({ source = { show = pick.default_show } }) +--- +--- - Mappings to switch `toggle_{preview,info}` and `move_{up,down}`: > +--- +--- require('mini.pick').setup({ +--- mappings = { +--- toggle_info = '', +--- toggle_preview = '', +--- move_down = '', +--- move_up = '', +--- } +--- }) +--- +--- - "Cursor tooltip" window style: > +--- +--- { +--- window = { +--- config = { +--- relative = 'cursor', anchor = 'NW', +--- row = 0, col = 0, width = 40, height = 20, +--- }, +--- }, +--- } +--- +--- - Change window border style: > +--- +--- { window = { config = { border = 'double' } } } +---@tag MiniPick-examples + +---@alias __pick_builtin_opts table|nil Options forwarded to |MiniPick.start()|. +---@alias __pick_builtin_local_opts table|nil Options defining behavior of this particular picker. + +---@diagnostic disable:undefined-field +---@diagnostic disable:discard-returns +---@diagnostic disable:unused-local +---@diagnostic disable:cast-local-type + +-- Module definition ========================================================== +local MiniPick = {} +local H = {} + +--- Module setup +--- +--- *:Pick* +--- Calling this function creates a `:Pick` user command. It takes picker name +--- from |MiniPick.registry| as mandatory first argument and executes it with +--- following (expanded, |expandcmd()|) || combined in a single table. +--- To add custom pickers, update |MiniPick.registry|. +--- +--- Example: > +--- +--- :Pick files tool='git' +--- :Pick grep pattern='' +--- +---@param config table|nil Module config table. See |MiniPick.config|. +--- +---@usage `require('mini.pick').setup({})` (replace `{}` with your `config` table). +MiniPick.setup = function(config) + -- Export module + _G.MiniPick = MiniPick + + -- Setup config + config = H.setup_config(config) + + -- Apply config + H.apply_config(config) + + -- Define behavior + H.create_autocommands(config) + + -- Create default highlighting + H.create_default_hl() + + -- Create user command + vim.api.nvim_create_user_command('Pick', function(input) + local name, local_opts = H.command_parse_fargs(input.fargs) + local f = MiniPick.registry[name] + if f == nil then H.error(string.format('There is no picker named "%s" in registry.', name)) end + f(local_opts) + end, { nargs = '+', complete = H.command_complete, desc = "Pick from 'mini.pick' registry" }) +end + +--stylua: ignore +--- Module config +--- +--- Default values: +---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section) +---@text # Delays ~ +--- +--- `config.delay` defines plugin delays (in ms). All should be strictly positive. +--- +--- `delay.async` is a delay between forcing asynchronous behavior. This usually +--- means making screen redraws and utilizing |MiniPick.poke_is_picker_active()| +--- (for example, to stop current matching if query has updated). +--- Smaller values give smoother user experience at the cost of more computations. +--- +--- `delay.busy` is a delay between when some computation starts and showing +--- visual feedback about it by making window border to have `MiniPickBorderBusy` +--- highlight group. +--- Smaller values will give feedback faster at the cost of feeling like flicker. +--- +--- # Mappings ~ +--- +--- `config.mappings` defines keys for special actions to be triggered after certain +--- keys. See |MiniPick-actions| for more information. +--- +--- # Options ~ +--- +--- `config.options` contains some general purpose options. +--- +--- `options.content_from_bottom` is a boolean indicating whether content should be +--- shown from bottom to top. That means that best matches will be shown at +--- the bottom. Note: for better experience use Neovim>=0.10, which has floating +--- window footer capability. Default: `false`. +--- +--- `options.use_cache` is a boolean indicating whether match results should be +--- cached per prompt (i.e. concatenated query). This results into faster response +--- on repeated prompts (like when deleting query entries) at the cost of using +--- more memory. Default: `false`. +--- +--- # Source ~ +--- +--- `config.source` defines fallbacks for source specification. For example, this +--- can be used to change default `match` to use different implementation or `show` +--- to not show icons for some |MiniPick.builtin| pickers (see |MiniPick-examples|). +--- See |MiniPick-source| for more information. +--- +--- # Window ~ +--- +--- `config.window` contains window specific configurations. +--- +--- `window.config` defines a (parts of) default floating window config for the main +--- picker window. This can be either a table overriding some parts or a callable +--- returning such table. See |MiniPick-examples| for some examples. +MiniPick.config = { + -- Delays (in ms; should be at least 1) + delay = { + -- Delay between forcing asynchronous behavior + async = 10, + + -- Delay between computation start and visual feedback about it + busy = 50, + }, + + -- Keys for performing actions. See `:h MiniPick-actions`. + mappings = { + caret_left = '', + caret_right = '', + + choose = '', + choose_in_split = '', + choose_in_tabpage = '', + choose_in_vsplit = '', + choose_marked = '', + + delete_char = '', + delete_char_right = '', + delete_left = '', + delete_word = '', + + mark = '', + mark_all = '', + + move_down = '', + move_start = '', + move_up = '', + + paste = '', + + refine = '', + refine_marked = '', + + scroll_down = '', + scroll_left = '', + scroll_right = '', + scroll_up = '', + + stop = '', + + toggle_info = '', + toggle_preview = '', + }, + + -- General options + options = { + -- Whether to show content from bottom to top + content_from_bottom = false, + + -- Whether to cache matches (more speed and memory on repeated prompts) + use_cache = false, + }, + + -- Source definition. See `:h MiniPick-source`. + source = { + items = nil, + name = nil, + cwd = nil, + + match = nil, + show = nil, + preview = nil, + + choose = nil, + choose_marked = nil, + }, + + -- Window related options + window = { + -- Float window config (table or callable returning it) + config = nil, + }, +} +--minidoc_afterlines_end + +--- Start picker +--- +--- Notes: +--- - If there is currently an active picker, it is properly stopped and new one +--- is started "soon" in the main event-loop (see |vim.schedule()|). +--- - Current window at the moment of this function call is treated as "target". +--- See |MiniPick.get_picker_state()| and |MiniPick.set_picker_target_window()|. +--- +---@param opts table|nil Options. Should have same structure as |MiniPick.config|. +--- Default values are inferred from there. +--- Usually should have proper |MiniPick-source.items| defined. +--- +---@return any Item which was current when picker is stopped; `nil` if aborted. +MiniPick.start = function(opts) + if MiniPick.is_picker_active() then + -- Try proper 'key query process' stop + MiniPick.stop() + -- NOTE: Needs `defer_fn()` for `stop()` to properly finish code flow and + -- not be executed before it + return vim.defer_fn(function() + -- NOTE: if `MiniPick.stop()` still didn't stop, force abort + if MiniPick.is_picker_active() then H.picker_stop(H.pickers.active, true) end + MiniPick.start(opts) + end, 0.5) + end + + opts = H.validate_picker_opts(opts) + local picker = H.picker_new(opts) + H.pickers.active, H.cache = picker, {} + + H.picker_set_busy(picker, true) + local items = H.expand_callable(opts.source.items) + -- - Set items on next event loop to not block when computing stritems + if vim.tbl_islist(items) then vim.schedule(function() MiniPick.set_picker_items(items) end) end + + H.picker_track_lost_focus(picker) + return H.picker_advance(picker) +end + +--- Stop active picker +MiniPick.stop = function() + if not MiniPick.is_picker_active() then return end + H.cache.is_force_stop_advance = true + if H.cache.is_in_getcharstr then vim.api.nvim_feedkeys('\3', 't', true) end +end + +--- Refresh active picker +MiniPick.refresh = function() + if not MiniPick.is_picker_active() then return end + H.picker_update(H.pickers.active, false, true) +end + +--- Default match +--- +--- Filter target stritems to contain query and sort from best to worst matches. +--- +--- Implements default value for |MiniPick-source.match|. +--- +--- By default (if no special modes apply) it does the following fuzzy matching: +--- +--- - Stritem contains query if it contains all its elements verbatim in the same +--- order (possibly with gaps, i.e. not strictly one after another). +--- Note: empty query and empty string element is contained in any string. +--- +--- - Sorting is done with the following ordering (same as in |mini.fuzzy|): +--- - The smaller the match width (end column minus start column) the better. +--- - Among same match width, the smaller start column the better. +--- - Among same match width and start column, preserve original order. +--- +--- Notes: +--- - Most common interactive usage results into `query` containing one typed +--- character per element. +--- +--- # Special modes ~ +--- +--- - Forced modes: +--- - Query starts with "*": match the rest fuzzy (without other modes). +--- - Query starts with "'": match the rest exactly (without gaps). +--- +--- - Place modes: +--- - Query starts with '^': match the rest exactly at start. +--- - Query ends with '$': match the rest exactly at end. +--- - Both modes can be used simultaneously. +--- +--- - Grouped: query contains at least one whitespace element. Output is computed +--- as if query is split at whitespace indexes with concatenation between them. +--- +--- Precedence of modes: +--- "forced exact" = "forced fuzzy" > "place start/end" > "grouped" > "default" +--- +--- # Examples ~ +--- +--- Assuming `stritems` are `{ '_abc', 'a_bc', 'ab_c', 'abc_' }`, here are some +--- example matches based on prompt (concatenated query): > +--- +--- | Prompt | Matches | +--- |--------|------------------------| +--- | abc | All | +--- | *abc | All | +--- | | | +--- | 'abc | abc_, _abc | +--- | *'abc | None (no "'" in items) | +--- | | | +--- | ^abc | abc_ | +--- | *^abc | None (no "^" in items) | +--- | | | +--- | abc$ | _abc | +--- | *abc$ | None (no "$" in items) | +--- | | | +--- | ab c | abc_, _abc, ab_c | +--- | *ab c | None (no " " in items) | +--- +--- Having query `{ 'ab', 'c' }` is the same as "ab c" prompt. +--- +--- You can have a feel of how this works with this command: > +--- +--- MiniPick.start({ source = { items = { '_abc', 'a_bc', 'ab_c', 'abc_' } } }) +--- +---@param stritems table Array of all stritems. +---@param inds table Array of `stritems` indexes to match. All of them should point +--- at string elements of `stritems`. No check is done for performance reasons. +---@param query table Array of strings. +--- +---@return table|nil Depending of whether there is an active picker: +--- - If yes, `nil` is returned with |MiniPick.set_picker_match_inds()| used later. +--- - If no, array of `stritems` indexes matching the `query` (from best to worst). +MiniPick.default_match = function(stritems, inds, query) + local is_active = MiniPick.is_picker_active() + local set_match_inds = is_active and MiniPick.set_picker_match_inds or function(x) return x end + local f = function() + if #query == 0 then return set_match_inds(H.seq_along(stritems)) end + local match_data, match_type = H.match_filter(inds, stritems, query) + if match_data == nil then return end + if match_type == 'nosort' then return set_match_inds(H.seq_along(stritems)) end + local match_inds = H.match_sort(match_data) + if match_inds == nil then return end + return set_match_inds(match_inds) + end + + if not is_active then return f() end + coroutine.resume(coroutine.create(f)) +end + +--- Default show +--- +--- Show items in a buffer and highlight parts that actually match query (assuming +--- match is done with |MiniPick.default_match()|). Lines are computed based on +--- the |MiniPick-source.items-stritems|. +--- +--- Implements default value for |MiniPick-source.show|. +--- +--- Uses the following highlight groups (see |MiniPick| for their description): +--- +--- * `MiniPickIconDirectory` +--- * `MiniPickIconFile` +--- * `MiniPickMatchCurrent` +--- * `MiniPickMatchMarked` +--- * `MiniPickMatchRanges` +--- +---@param buf_id number Identifier of target buffer. +---@param items table Array of items to show. +---@param query table Array of strings representing query. +---@param opts table|nil Options. Possible fields: +--- - `(boolean)` - whether to show icons for entries recognized as +--- valid actually present paths on disk (see |MiniPick-source.items-common|), +--- empty space otherwise. +--- Default: `false`. Note: |MiniPick.builtin| pickers showing file/directory +--- paths use `true` by default. +MiniPick.default_show = function(buf_id, items, query, opts) + opts = vim.tbl_deep_extend('force', { show_icons = false }, opts or {}) + + -- Compute and set lines + local lines = vim.tbl_map(H.item_to_string, items) + local tab_spaces = string.rep(' ', vim.o.tabstop) + lines = vim.tbl_map(function(l) return l:gsub('\n', ' '):gsub('\t', tab_spaces) end, lines) + + local get_prefix_data = opts.show_icons and H.get_icon or function() return { text = '' } end + local prefix_data = vim.tbl_map(get_prefix_data, lines) + + local lines_to_show = {} + for i, l in ipairs(lines) do + lines_to_show[i] = prefix_data[i].text .. l + end + + H.set_buflines(buf_id, lines_to_show) + + -- Extract match ranges + local ns_id = H.ns_id.ranges + H.clear_namespace(buf_id, ns_id) + + if H.query_is_ignorecase(query) then + lines, query = vim.tbl_map(H.tolower, lines), vim.tbl_map(H.tolower, query) + end + local match_data, match_type, query_adjusted = H.match_filter(H.seq_along(lines), lines, query) + if match_data == nil then return end + + local match_ranges_fun = match_type == 'fuzzy' and H.match_ranges_fuzzy or H.match_ranges_exact + local match_ranges = match_ranges_fun(match_data, query_adjusted, lines) + + -- Place range highlights accounting for possible shift due to prefixes + local extmark_opts = { hl_group = 'MiniPickMatchRanges', hl_mode = 'combine', priority = 200 } + for i = 1, #match_data do + local row, ranges = match_data[i][3], match_ranges[i] + local start_offset = prefix_data[row].text:len() + for _, range in ipairs(ranges) do + extmark_opts.end_row, extmark_opts.end_col = row - 1, start_offset + range[2] + H.set_extmark(buf_id, ns_id, row - 1, start_offset + range[1] - 1, extmark_opts) + end + end + + -- Highlight prefixes + if not opts.show_icons then return end + local icon_extmark_opts = { hl_mode = 'combine', priority = 200 } + for i = 1, #prefix_data do + icon_extmark_opts.hl_group = prefix_data[i].hl + icon_extmark_opts.end_row, icon_extmark_opts.end_col = i - 1, prefix_data[i].text:len() + H.set_extmark(buf_id, ns_id, i - 1, 0, icon_extmark_opts) + end +end + +--- Default preview +--- +--- Preview item. Logic follows the rules in |MiniPick-source.items-common|: +--- - File and buffer are shown at the start. +--- - Directory has its content listed. +--- - Line/position/region in file or buffer is shown at start. +--- - Others are shown directly with |vim.inspect()|. +--- +--- Implements default value for |MiniPick-source.preview|. +--- +--- Uses the following highlight groups (see |MiniPick| for their description): +--- +--- * `MiniPickPreviewLine` +--- * `MiniPickPreviewRegion` +--- +---@param buf_id number Identifier of target buffer. +---@param item any Item to preview. +---@param opts table|nil Options. Possible values: +--- - `(number)` - number of lines to load past target position +--- when reading from disk. Useful to explore context. Default: 'lines' twice. +--- - `(string)` - where in the window to show item position. +--- One of "top", "center", "bottom". Default: "top". +MiniPick.default_preview = function(buf_id, item, opts) + opts = vim.tbl_deep_extend('force', { n_context_lines = 2 * vim.o.lines, line_position = 'top' }, opts or {}) + local item_data = H.parse_item(item) + if item_data.type == 'file' then return H.preview_file(buf_id, item_data, opts) end + if item_data.type == 'directory' then return H.preview_directory(buf_id, item_data) end + if item_data.type == 'buffer' then return H.preview_buffer(buf_id, item_data, opts) end + H.preview_inspect(buf_id, item) +end + +--- Default choose +--- +--- Choose item. Logic follows the rules in |MiniPick-source.items-common|: +--- - File and directory are called with |:edit| in the target window, possibly +--- followed by setting cursor at the start of line/position/region. +--- - Buffer is set as current in target window. +--- - Others have the output of |vim.inspect()| printed in Command line. +--- +--- Implements default value for |MiniPick-source.choose|. +--- +---@param item any Item to choose. +MiniPick.default_choose = function(item) + if item == nil then return end + local picker_state = MiniPick.get_picker_state() + local win_target = picker_state ~= nil and picker_state.windows.target or vim.api.nvim_get_current_win() + if not H.is_valid_win(win_target) then win_target = H.get_first_valid_normal_window() end + + local item_data = H.parse_item(item) + if item_data.type == 'file' or item_data.type == 'directory' then return H.choose_path(win_target, item_data) end + if item_data.type == 'buffer' then return H.choose_buffer(win_target, item_data) end + H.choose_print(item) +end + +--- Default choose marked items +--- +--- Choose marked items. Logic follows the rules in |MiniPick-source.items-common|: +--- - If among items there is at least one file or buffer, quickfix list is opened +--- with all file or buffer lines/positions/regions. +--- - Otherwise, picker's `source.choose` is called on the first item. +--- +--- Implements default value for |MiniPick-source.choose_marked|. +--- +---@param items table Array of items to choose. +---@param opts Options. Possible fields: +--- - `(string)` - which type of list to open. One of "quickfix" +--- or "location". Default: "quickfix". +MiniPick.default_choose_marked = function(items, opts) + if not vim.tbl_islist(items) then H.error('`items` should be an array') end + if #items == 0 then return end + opts = vim.tbl_deep_extend('force', { list_type = 'quickfix' }, opts or {}) + + -- Construct a potential quickfix/location list + local list = {} + for _, item in ipairs(items) do + local item_data = H.parse_item(item) + if item_data.type == 'file' or item_data.type == 'buffer' then + local entry = { bufnr = item_data.buf_id, filename = item_data.path } + entry.lnum, entry.col, entry.text = item_data.lnum or 1, item_data.col or 1, item_data.text or '' + entry.end_lnum, entry.end_col = item_data.end_lnum, item_data.end_col + table.insert(list, entry) + end + end + + -- Fall back to choosing first item if no quickfix list was constructed + local is_active = MiniPick.is_picker_active() + if #list == 0 then + if not is_active then return end + local choose = MiniPick.get_picker_opts().source.choose + return choose(items[1]) + end + + -- Set as quickfix or location list + local title = '' + if is_active then + local source_name, prompt = MiniPick.get_picker_opts().source.name, table.concat(MiniPick.get_picker_query()) + title = source_name .. (prompt == '' and '' or (' : ' .. prompt)) + end + local list_data = { items = list, title = title, nr = '$' } + + if opts.list_type == 'location' then + local win_target = MiniPick.get_picker_state().windows.target + if not H.is_valid_win(win_target) then win_target = H.get_first_valid_normal_window() end + vim.fn.setloclist(win_target, {}, ' ', list_data) + vim.schedule(function() vim.cmd('lopen') end) + else + vim.fn.setqflist({}, ' ', list_data) + vim.schedule(function() vim.cmd('copen') end) + end +end + +--- Select rewrite +--- +--- Function which can be used to directly override |vim.ui.select()| to use +--- 'mini.pick' for any "select" type of tasks. +--- +--- Implements the required by `vim.ui.select()` signature. Plus allows extra +--- `opts.preview_item` to serve as preview. +MiniPick.ui_select = function(items, opts, on_choice) + local format_item = opts.format_item or H.item_to_string + local items_ext = {} + for i = 1, #items do + table.insert(items_ext, { text = format_item(items[i]), item = items[i], index = i }) + end + + local preview_item = vim.is_callable(opts.preview_item) and opts.preview_item + or function(x) return vim.split(vim.inspect(x), '\n') end + local preview = function(buf_id, item) H.set_buflines(buf_id, preview_item(item.item)) end + + local was_aborted = true + local choose = function(item) + was_aborted = false + if item == nil then return end + on_choice(item.item, item.index) + MiniPick.set_picker_target_window(vim.api.nvim_get_current_win()) + end + + local source = { items = items_ext, name = opts.kind or opts.prompt, preview = preview, choose = choose } + local item = MiniPick.start({ source = source }) + if item == nil and was_aborted then on_choice(nil) end +end + +--- Table with built-in pickers +MiniPick.builtin = {} + +--- Pick from files +--- +--- Lists all files: recursively in all subdirectories including hidden files. +--- Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +--- `rg`, `fd`, `git`. If none is present, uses fallback which utilizes |vim.fs.dir()|. +--- +---@param local_opts __pick_builtin_local_opts +--- Possible fields: +--- - `(string)` - which tool to use. One of "rg", "fd", "git", "fallback". +--- Default: whichever tool is present, trying in that same order. +---@param opts __pick_builtin_opts +MiniPick.builtin.files = function(local_opts, opts) + local_opts = vim.tbl_deep_extend('force', { tool = nil }, local_opts or {}) + local tool = local_opts.tool or H.files_get_tool() + local show = H.get_config().source.show or H.show_with_icons + local default_opts = { source = { name = string.format('Files (%s)', tool), show = show } } + opts = vim.tbl_deep_extend('force', default_opts, opts or {}) + + if tool == 'fallback' then + opts.source.items = function() H.files_fallback_items(opts.source.cwd) end + return MiniPick.start(opts) + end + + return MiniPick.builtin.cli({ command = H.files_get_command(tool) }, opts) +end + +--- Pick from pattern matches +--- +--- Lists all pattern matches: recursively in all subdirectories including +--- hidden files. +--- Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +--- `rg`, `git`. If none is present, uses fallback which utilizes |vim.fs.dir()| and +--- Lua pattern matches (NOT recommended in large directories). +--- +---@param local_opts __pick_builtin_local_opts +--- Possible fields: +--- - `(string)` - which tool to use. One of "rg", "git", "fallback". +--- Default: whichever tool is present, trying in that same order. +--- - `(string)` - string pattern to search. If not given, asks user +--- interactively with |input()|. +---@param opts __pick_builtin_opts +MiniPick.builtin.grep = function(local_opts, opts) + local_opts = vim.tbl_deep_extend('force', { tool = nil, pattern = nil }, local_opts or {}) + local tool = local_opts.tool or H.grep_get_tool() + local show = H.get_config().source.show or H.show_with_icons + local default_opts = { source = { name = string.format('Grep (%s)', tool), show = show } } + opts = vim.tbl_deep_extend('force', default_opts, opts or {}) + + local pattern = type(local_opts.pattern) == 'string' and local_opts.pattern or vim.fn.input('Grep pattern: ') + if tool == 'fallback' then + opts.source.items = function() H.grep_fallback_items(pattern, opts.source.cwd) end + return MiniPick.start(opts) + end + + return MiniPick.builtin.cli({ command = H.grep_get_command(tool, pattern) }, opts) +end + +--- Pick from pattern matches with live feedback +--- +--- Perform pattern matching treating prompt as pattern. Gives live feedback on +--- which matches are found. Use |MiniPick-actions-refine| to revert to regular +--- matching. +--- Tries to use one of the CLI tools to create items (see |MiniPick-cli-tools|): +--- `rg`, `git`. If none is present, error is thrown (for performance reasons). +--- +---@param local_opts __pick_builtin_local_opts +--- Possible fields: +--- - `(string)` - which tool to use. One of "rg", "git". +--- Default: whichever tool is present, trying in that same order. +---@param opts __pick_builtin_opts +MiniPick.builtin.grep_live = function(local_opts, opts) + local_opts = vim.tbl_deep_extend('force', { tool = nil }, local_opts or {}) + local tool = local_opts.tool or H.grep_get_tool() + if tool == 'fallback' or not H.is_executable(tool) then H.error('`grep_live` needs non-fallback executable tool.') end + + local show = H.get_config().source.show or H.show_with_icons + local default_opts = { source = { name = string.format('Grep live (%s)', tool), show = show } } + opts = vim.tbl_deep_extend('force', default_opts, opts or {}) + + local set_items_opts, spawn_opts = { do_match = false, querytick = H.querytick }, { cwd = opts.source.cwd } + local process + local match = function(_, _, query) + pcall(vim.loop.process_kill, process) + if H.querytick == set_items_opts.querytick then return end + if #query == 0 then return MiniPick.set_picker_items({}, set_items_opts) end + + set_items_opts.querytick = H.querytick + local command = H.grep_get_command(tool, table.concat(query)) + process = MiniPick.set_picker_items_from_cli(command, { set_items_opts = set_items_opts, spawn_opts = spawn_opts }) + end + + opts = vim.tbl_deep_extend('force', opts or {}, { source = { items = {}, match = match } }) + return MiniPick.start(opts) +end + +--- Pick from help tags +--- +---@param local_opts __pick_builtin_local_opts +--- Not used at the moment. +---@param opts __pick_builtin_opts +MiniPick.builtin.help = function(local_opts, opts) + -- Get all tags + local help_buf = vim.api.nvim_create_buf(false, true) + vim.bo[help_buf].buftype = 'help' + local tags = vim.api.nvim_buf_call(help_buf, function() return vim.fn.taglist('.*') end) + vim.api.nvim_buf_delete(help_buf, { force = true }) + vim.tbl_map(function(t) t.text = t.name end, tags) + + -- NOTE: Choosing is done after returning item. This is done to properly + -- overcome special nature of `:help {subject}` command. For example, it + -- didn't quite work when choosing tags in same file consecutively. + local choose = function(item) end + local choose_marked = function(items) end + local preview = function(buf_id, item) + -- Take advantage of `taglist` output on how to open tag + vim.api.nvim_buf_call(buf_id, function() + vim.cmd('noautocmd edit ' .. vim.fn.fnameescape(item.filename)) + vim.bo.buflisted, vim.bo.bufhidden, vim.bo.syntax = false, 'wipe', 'help' + + local cache_hlsearch = vim.v.hlsearch + -- Make a "very nomagic" search to account for special characters in tag + local search_cmd = string.gsub(item.cmd, '^/', '/\\V') + vim.cmd('silent keeppatterns ' .. search_cmd) + -- Here `vim.v` doesn't work: https://github.com/neovim/neovim/issues/25294 + vim.cmd('let v:hlsearch=' .. cache_hlsearch) + vim.cmd('normal! zt') + end) + end + + local source = { items = tags, name = 'Help', choose = choose, choose_marked = choose_marked, preview = preview } + opts = vim.tbl_deep_extend('force', { source = source }, opts or {}) + local item = MiniPick.start(opts) + if item ~= nil then vim.cmd('help ' .. (item.name or '')) end + return item +end + +--- Pick from buffers +--- +---@param local_opts __pick_builtin_local_opts +--- Possible fields: +--- - `(boolean)` - whether to include current buffer in +--- the output. Default: `true`. +--- - `(boolean)` - whether to include |unlisted-buffer|s in +--- the output. Default: `false`. +---@param opts __pick_builtin_opts +MiniPick.builtin.buffers = function(local_opts, opts) + local_opts = vim.tbl_deep_extend('force', { include_current = true, include_unlisted = false }, local_opts or {}) + + local buffers_output = vim.api.nvim_exec('buffers' .. (local_opts.include_unlisted and '!' or ''), true) + local cur_buf_id, include_current = vim.api.nvim_get_current_buf(), local_opts.include_current + local items = {} + for _, l in ipairs(vim.split(buffers_output, '\n')) do + local buf_str, name = l:match('^%s*%d+'), l:match('"(.*)"') + local buf_id = tonumber(buf_str) + local item = { text = name, bufnr = buf_id } + if buf_id ~= cur_buf_id or include_current then table.insert(items, item) end + end + + local show = H.get_config().source.show or H.show_with_icons + local default_opts = { source = { name = 'Buffers', show = show } } + opts = vim.tbl_deep_extend('force', default_opts, opts or {}, { source = { items = items } }) + return MiniPick.start(opts) +end + +--- Pick from CLI output +--- +--- Executes command line tool and constructs items based on its output. +--- Uses |MiniPick.set_picker_items_from_cli()|. +--- +--- Example: `MiniPick.builtin.cli({ command = { 'echo', 'a\nb\nc' } })` +--- +---@param local_opts __pick_builtin_local_opts +--- Possible fields: +--- - `(table)` - forwarded to `set_picker_items_from_cli()`. +--- - `(function)` - forwarded to `set_picker_items_from_cli()`. +--- - `(table)` - forwarded to `set_picker_items_from_cli()`. +--- Note: if `cwd` field is absent, it is inferred from |MiniPick-source.cwd|. +---@param opts __pick_builtin_opts +MiniPick.builtin.cli = function(local_opts, opts) + local_opts = vim.tbl_deep_extend('force', { command = {}, postprocess = nil, spawn_opts = {} }, local_opts or {}) + local name = string.format('CLI (%s)', tostring(local_opts.command[1] or '')) + opts = vim.tbl_deep_extend('force', { source = { name = name } }, opts or {}) + local_opts.spawn_opts.cwd = local_opts.spawn_opts.cwd or opts.source.cwd + + local command = local_opts.command + local set_from_cli_opts = { postprocess = local_opts.postprocess, spawn_opts = local_opts.spawn_opts } + opts.source.items = vim.schedule_wrap(function() MiniPick.set_picker_items_from_cli(command, set_from_cli_opts) end) + return MiniPick.start(opts) +end + +--- Resume latest picker +MiniPick.builtin.resume = function() + local picker = H.pickers.latest + if picker == nil then H.error('There is no picker to resume.') end + + local buf_id = H.picker_new_buf() + local win_target = vim.api.nvim_get_current_win() + local win_id = H.picker_new_win(buf_id, picker.opts.window.config) + picker.buffers = { main = buf_id } + picker.windows = { main = win_id, target = win_target } + picker.view_state = 'main' + + H.pickers.active, H.cache = picker, {} + return H.picker_advance(picker) +end + +--- Picker registry +--- +--- Place for users and extensions to manage pickers with their commonly used +--- global options. By default contains all |MiniPick.builtin| entries. +--- +--- Serves as a source for |:Pick| command. +--- +--- Customization examples: > +--- +--- -- Adding custom picker +--- require('mini.pick').registry.arglist = function() +--- local source = { items = vim.fn.argv, name = 'Arglist' } +--- return MiniPick.start({ source = source }) +--- end +--- +--- -- Make `:Pick files` accept `cwd` +--- MiniPick.registry.files = function(local_opts) +--- local opts = { source = { cwd = local_opts.cwd } } +--- local_opts.cwd = nil +--- return MiniPick.builtin.files(local_opts, opts) +--- end +MiniPick.registry = {} + +for name, f in pairs(MiniPick.builtin) do + MiniPick.registry[name] = function(local_opts) return f(local_opts) end +end + +if type(MiniExtra) == 'table' then + for name, f in pairs(MiniExtra.pickers) do + MiniPick.registry[name] = function(local_opts) return f(local_opts) end + end +end + +--- Get items of active picker +--- +---@return table|nil Picker items or `nil` if no active picker. +--- +---@seealso |MiniPick.set_picker_items()| and |MiniPick.set_picker_items_from_cli()| +MiniPick.get_picker_items = function() return vim.deepcopy((H.pickers.active or {}).items) end + +--- Get stritems of active picker +--- +---@return table|nil Picker stritems (|MiniPick-source.items-stritems|) or `nil` if +--- no active picker. +--- +---@seealso |MiniPick.set_picker_items()| and |MiniPick.set_picker_items_from_cli()| +MiniPick.get_picker_stritems = function() return vim.deepcopy((H.pickers.active or {}).stritems) end + +--- Get matches of active picker +--- +---@return table|nil Picker matches or `nil` if no active picker. Matches is a table +--- with the following fields: +--- - `(table|nil)` - all currently matched items. +--- - `(table|nil)` - indexes of all currently matched items. +--- - `(any)` - current matched item. +--- - `(number|nil)` - index of current matched item. +--- - `(table|nil)` - marked items. +--- - `(table|nil)` - indexes of marked items. +--- +---@seealso |MiniPick.set_picker_match_inds()| +MiniPick.get_picker_matches = function() + if not MiniPick.is_picker_active() then return end + local picker = H.pickers.active + local items = picker.items + if items == nil or #items == 0 then return {} end + + local res = { all_inds = vim.deepcopy(picker.match_inds), current_ind = picker.match_inds[picker.current_ind] } + res.all = vim.tbl_map(function(ind) return items[ind] end, picker.match_inds) + res.current = picker.items[res.current_ind] + local marked_inds = vim.tbl_keys(picker.marked_inds_map) + table.sort(marked_inds) + res.marked_inds, res.marked = marked_inds, vim.tbl_map(function(ind) return items[ind] end, marked_inds) + return res +end + +--- Get config of active picker +--- +---@return table|nil Picker config (`start()`'s input `opts` table) or `nil` if +--- no active picker. +--- +---@seealso |MiniPick.set_picker_opts()| +MiniPick.get_picker_opts = function() return vim.deepcopy((H.pickers.active or {}).opts) end + +--- Get state data of active picker +--- +---@return table|nil Table with picker state data or `nil` if no active picker. +--- State data is a table with the following fields: +--- - `(table)` - table with `main`, `preview`, `info` fields representing +--- buffer identifier (or `nil`) for corresponding view. +--- - `(table)` - table with `main` and `target` fields representing +--- window identifiers for main and target windows. +--- - `(number)` - caret column. +--- - `(boolean)` - whether picker is busy with computations. +--- +---@seealso |MiniPick.set_picker_target_window()| +MiniPick.get_picker_state = function() + if not MiniPick.is_picker_active() then return end + local picker = H.pickers.active + --stylua: ignore + return vim.deepcopy({ + buffers = picker.buffers, windows = picker.windows, caret = picker.caret, is_busy = picker.is_busy + }) +end + +--- Get query of active picker +--- +---@return table|nil Array of picker query or `nil` if no active picker. +--- +---@seealso |MiniPick.set_picker_query()| +MiniPick.get_picker_query = function() return vim.deepcopy((H.pickers.active or {}).query) end + +--- Set items for active picker +--- +--- Note: sets items asynchronously in non-blocking fashion. +--- +---@param items table Array of items. +---@param opts table|nil Options. Possible fields: +--- - `(boolean)` - whether to perform match after setting items. +--- Default: `true`. +--- - `(number|nil)` - value of querytick (|MiniPick.get_querytick()|) +--- to periodically check against when setting items. If checked querytick +--- differs from supplied, no items are set. +--- +---@seealso |MiniPick.get_picker_items()| and |MiniPick.get_picker_stritems()| +MiniPick.set_picker_items = function(items, opts) + if not vim.tbl_islist(items) then H.error('`items` should be an array.') end + if not MiniPick.is_picker_active() then return end + opts = vim.tbl_deep_extend('force', { do_match = true, querytick = nil }, opts or {}) + + -- Set items in async because computing lower `stritems` can block much time + coroutine.wrap(H.picker_set_items)(H.pickers.active, items, opts) +end + +--- Set items for active picker based on CLI output +--- +--- Asynchronously executes `command` and sets items to its postprocessed output. +--- +--- Example: > +--- local items = vim.schedule_wrap(function() +--- MiniPick.set_picker_items_from_cli({ 'echo', 'a\nb\nc' }) +--- end) +--- MiniPick.start({ source = { items = items, name = 'Echo abc' } }) +--- +---@param command table Array with (at least one) string command parts. +---@param opts table|nil Options. Possible fields: +--- - `(function)` - callable performing postprocessing of output. +--- Will be called with array of lines as input, should return array of items. +--- Default: removes trailing empty lines and uses rest as string items. +--- - `(table)` - `options` for |uv.spawn|, except `args` and `stdio` fields. +--- - `(table)` - table forwarded to |MiniPick.set_picker_items()|. +--- +---@seealso |MiniPick.get_picker_items()| and |MiniPick.get_picker_stritems()| +MiniPick.set_picker_items_from_cli = function(command, opts) + if not MiniPick.is_picker_active() then return end + local is_valid_command = H.is_array_of(command, 'string') and #command >= 1 + if not is_valid_command then H.error('`command` should be an array of strings.') end + local default_opts = { postprocess = H.cli_postprocess, set_items_opts = {}, spawn_opts = {} } + opts = vim.tbl_deep_extend('force', default_opts, opts or {}) + + local executable, args = command[1], vim.list_slice(command, 2, #command) + local process, pid, stdout = nil, nil, vim.loop.new_pipe() + local spawn_opts = vim.tbl_deep_extend('force', opts.spawn_opts, { args = args, stdio = { nil, stdout, nil } }) + if type(spawn_opts.cwd) == 'string' then spawn_opts.cwd = H.full_path(spawn_opts.cwd) end + process, pid = vim.loop.spawn(executable, spawn_opts, function() process:close() end) + + local data_feed = {} + stdout:read_start(function(err, data) + assert(not err, err) + if data ~= nil then return table.insert(data_feed, data) end + + local items = vim.split(table.concat(data_feed), '\n') + data_feed = nil + stdout:close() + vim.schedule(function() MiniPick.set_picker_items(opts.postprocess(items), opts.set_items_opts) end) + end) + + return process, pid +end + +--- Set match indexes for active picker +--- +--- This is intended to be used inside custom asynchronous |MiniPick-source.match| +--- implementations. See |MiniPick.poke_is_picker_active()| for an example. +--- +---@param match_inds table Array of numbers indicating which elements of picker's +--- stritems match the query. +--- +---@seealso |MiniPick.get_picker_matches()| +MiniPick.set_picker_match_inds = function(match_inds) + if not MiniPick.is_picker_active() then return end + if not H.is_array_of(match_inds, 'number') then H.error('`match_inds` should be an array of numbers.') end + H.picker_set_match_inds(H.pickers.active, match_inds) + H.picker_update(H.pickers.active, false) +end + +--- Set config for active picker +--- +---@param opts table Table overriding initial `opts` input of |MiniPick.start()|. +--- +---@seealso |MiniPick.get_picker_opts()| +MiniPick.set_picker_opts = function(opts) + if not MiniPick.is_picker_active() then return end + H.pickers.active.opts = vim.tbl_deep_extend('force', H.pickers.active.opts, opts or {}) + H.picker_update(H.pickers.active, true, true) +end + +--- Set target window for active picker +--- +---@param win_id number Valid window identifier to be used as the new target window. +--- +---@seealso |MiniPick.get_picker_state()| +MiniPick.set_picker_target_window = function(win_id) + if not MiniPick.is_picker_active() then return end + if not H.is_valid_win(win_id) then H.error('`win_id` is not a valid window identifier.') end + H.pickers.active.windows.target = win_id +end + +--- Set query for active picker +--- +---@param query table Array of strings to be set as the new picker query. +--- +---@seealso |MiniPick.get_picker_query()| +MiniPick.set_picker_query = function(query) + if not MiniPick.is_picker_active() then return end + if not H.is_array_of(query, 'string') then H.error('`query` should be an array of strings.') end + + H.pickers.active.query, H.pickers.active.caret = query, #query + 1 + H.querytick = H.querytick + 1 + H.pickers.active.match_inds = H.seq_along(MiniPick.get_picker_items()) + H.picker_update(H.pickers.active, true) +end + +--- Get query tick +--- +--- Query tick is a unique query identifier. Intended to be used to detect user +--- activity during and between |MiniPick.start()| calls for efficient non-blocking +--- functionality. Updates after any query change, picker start and stop. +--- +--- See |MiniPick.poke_is_picker_active()| for usage example. +--- +---@return number Query tick. +MiniPick.get_querytick = function() return H.querytick end + +--- Check if there is an active picker +--- +---@return boolean Whether there is currently an active picker. +--- +---@seealso |MiniPick.poke_is_picker_active()| +MiniPick.is_picker_active = function() return H.pickers.active ~= nil end + +--- Poke if picker is active +--- +--- Intended to be used for non-blocking implementation of source methods. +--- Returns an output of |MiniPick.is_picker_active()|, but depending on +--- whether there is a coroutine running: +--- - If no, return it immediately. +--- - If yes, return it after `coroutine.yield()` with `coroutine.resume()` +--- called "soon" by the main event-loop (see |vim.schedule()|). +--- +--- Example of non-blocking exact `match` (as demo; can be optimized further): > +--- +--- local match_nonblock = function(match_inds, stritems, query) +--- local prompt, querytick = table.concat(query), MiniPick.get_querytick() +--- local f = function() +--- local res = {} +--- for _, ind in ipairs(match_inds) do +--- local should_stop = not MiniPick.poke_is_picker_active() or +--- MiniPick.get_querytick() ~= querytick +--- if should_stop then return end +--- +--- if stritems[ind]:find(prompt) ~= nil then table.insert(res, ind) end +--- end +--- +--- MiniPick.set_picker_match_inds(res) +--- end +--- +--- coroutine.resume(coroutine.create(f)) +--- end +--- +---@return boolean Whether there is an active picker. +--- +---@seealso |MiniPick.is_picker_active()| +MiniPick.poke_is_picker_active = function() + local co = coroutine.running() + if co == nil then return MiniPick.is_picker_active() end + H.schedule_resume_is_active(co) + return coroutine.yield() +end + +-- Helper data ================================================================ +-- Module default config +H.default_config = vim.deepcopy(MiniPick.config) + +-- Namespaces +H.ns_id = { + matches = vim.api.nvim_create_namespace('MiniPickMatches'), + headers = vim.api.nvim_create_namespace('MiniPickHeaders'), + preview = vim.api.nvim_create_namespace('MiniPickPreview'), + ranges = vim.api.nvim_create_namespace('MiniPickRanges'), +} + +-- Timers +H.timers = { + busy = vim.loop.new_timer(), + focus = vim.loop.new_timer(), + getcharstr = vim.loop.new_timer(), +} + +-- Pickers +H.pickers = { active = nil, latest = nil } + +-- Picker-independent counter of query updates +H.querytick = 0 + +-- General purpose cache +H.cache = {} + +-- Helper functionality ======================================================= +-- Settings ------------------------------------------------------------------- +H.setup_config = function(config) + -- General idea: if some table elements are not present in user-supplied + -- `config`, take them from default config + vim.validate({ config = { config, 'table', true } }) + config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {}) + + vim.validate({ + delay = { config.delay, 'table' }, + mappings = { config.mappings, 'table' }, + options = { config.options, 'table' }, + source = { config.source, 'table' }, + window = { config.window, 'table' }, + }) + + vim.validate({ + ['delay.async'] = { config.delay.async, 'number' }, + ['delay.busy'] = { config.delay.busy, 'number' }, + + ['mappings.caret_left'] = { config.mappings.caret_left, 'string' }, + ['mappings.caret_right'] = { config.mappings.caret_right, 'string' }, + ['mappings.choose'] = { config.mappings.choose, 'string' }, + ['mappings.choose_in_split'] = { config.mappings.choose_in_split, 'string' }, + ['mappings.choose_in_tabpage'] = { config.mappings.choose_in_tabpage, 'string' }, + ['mappings.choose_in_vsplit'] = { config.mappings.choose_in_vsplit, 'string' }, + ['mappings.choose_marked'] = { config.mappings.choose_marked, 'string' }, + ['mappings.delete_char'] = { config.mappings.delete_char, 'string' }, + ['mappings.delete_char_right'] = { config.mappings.delete_char_right, 'string' }, + ['mappings.delete_left'] = { config.mappings.delete_left, 'string' }, + ['mappings.delete_word'] = { config.mappings.delete_word, 'string' }, + ['mappings.mark'] = { config.mappings.mark, 'string' }, + ['mappings.mark_all'] = { config.mappings.mark_all, 'string' }, + ['mappings.move_down'] = { config.mappings.move_down, 'string' }, + ['mappings.move_start'] = { config.mappings.move_start, 'string' }, + ['mappings.move_up'] = { config.mappings.move_up, 'string' }, + ['mappings.paste'] = { config.mappings.paste, 'string' }, + ['mappings.refine'] = { config.mappings.refine, 'string' }, + ['mappings.refine_marked'] = { config.mappings.refine_marked, 'string' }, + ['mappings.scroll_down'] = { config.mappings.scroll_down, 'string' }, + ['mappings.scroll_up'] = { config.mappings.scroll_up, 'string' }, + ['mappings.scroll_left'] = { config.mappings.scroll_left, 'string' }, + ['mappings.scroll_right'] = { config.mappings.scroll_right, 'string' }, + ['mappings.stop'] = { config.mappings.stop, 'string' }, + ['mappings.toggle_info'] = { config.mappings.toggle_info, 'string' }, + ['mappings.toggle_preview'] = { config.mappings.toggle_preview, 'string' }, + + ['options.content_from_bottom'] = { config.options.content_from_bottom, 'boolean' }, + ['options.use_cache'] = { config.options.use_cache, 'boolean' }, + + ['source.items'] = { config.source.items, 'table', true }, + ['source.name'] = { config.source.name, 'string', true }, + ['source.cwd'] = { config.source.cwd, 'string', true }, + ['source.match'] = { config.source.match, 'function', true }, + ['source.show'] = { config.source.show, 'function', true }, + ['source.preview'] = { config.source.preview, 'function', true }, + ['source.choose'] = { config.source.choose, 'function', true }, + ['source.choose_marked'] = { config.source.choose_marked, 'function', true }, + + ['window.config'] = { + config.window.config, + function(x) return x == nil or type(x) == 'table' or vim.is_callable(x) end, + 'table or callable', + }, + }) + + return config +end + +H.apply_config = function(config) MiniPick.config = config end + +H.get_config = + function(config) return vim.tbl_deep_extend('force', MiniPick.config, vim.b.minipick_config or {}, config or {}) end + +H.create_autocommands = function(config) + local augroup = vim.api.nvim_create_augroup('MiniPick', {}) + + local au = function(event, pattern, callback, desc) + vim.api.nvim_create_autocmd(event, { group = augroup, pattern = pattern, callback = callback, desc = desc }) + end + + au('VimResized', '*', MiniPick.refresh, 'Refresh on resize') +end + +--stylua: ignore +H.create_default_hl = function() + local hi = function(name, opts) + opts.default = true + vim.api.nvim_set_hl(0, name, opts) + end + + hi('MiniPickBorder', { link = 'FloatBorder' }) + hi('MiniPickBorderBusy', { link = 'DiagnosticFloatingWarn' }) + hi('MiniPickBorderText', { link = 'FloatTitle' }) + hi('MiniPickIconDirectory', { link = 'Directory' }) + hi('MiniPickIconFile', { link = 'MiniPickNormal' }) + hi('MiniPickHeader', { link = 'DiagnosticFloatingHint' }) + hi('MiniPickMatchCurrent', { link = 'CursorLine' }) + hi('MiniPickMatchMarked', { link = 'Visual' }) + hi('MiniPickMatchRanges', { link = 'DiagnosticFloatingHint' }) + hi('MiniPickNormal', { link = 'NormalFloat' }) + hi('MiniPickPreviewLine', { link = 'CursorLine' }) + hi('MiniPickPreviewRegion', { link = 'IncSearch' }) + hi('MiniPickPrompt', { link = 'DiagnosticFloatingInfo' }) +end + +-- Command -------------------------------------------------------------------- +H.command_parse_fargs = function(fargs) + local name, opts_parts = fargs[1], vim.tbl_map(H.expandcmd, vim.list_slice(fargs, 2, #fargs)) + local tbl_string = string.format('{ %s }', table.concat(opts_parts, ', ')) + local lua_load = loadstring('return ' .. tbl_string) + if lua_load == nil then H.error('Could not convert extra command arguments to table: ' .. tbl_string) end + return name, lua_load() +end + +H.command_complete = function(_, line, col) + local prefix_from, prefix_to, prefix = string.find(line, '^%S+%s+(%S*)') + if col < prefix_from or prefix_to < col then return {} end + local candidates = vim.tbl_filter( + function(x) return tostring(x):find(prefix, 1, true) ~= nil end, + vim.tbl_keys(MiniPick.registry) + ) + table.sort(candidates) + return candidates +end + +-- Picker object -------------------------------------------------------------- +H.validate_picker_opts = function(opts) + opts = opts or {} + if type(opts) ~= 'table' then H.error('Picker options should be table.') end + + opts = vim.deepcopy(H.get_config(opts)) + + local validate_callable = function(x, x_name) + if not vim.is_callable(x) then H.error(string.format('`%s` should be callable.', x_name)) end + end + + -- Source + local source = opts.source + + local items = source.items or {} + local is_valid_items = vim.tbl_islist(items) or vim.is_callable(items) + if not is_valid_items then H.error('`source.items` should be array or callable.') end + + source.name = tostring(source.name or '') + + if type(source.cwd) == 'string' then source.cwd = H.full_path(source.cwd) end + if source.cwd == nil then source.cwd = vim.fn.getcwd() end + if vim.fn.isdirectory(source.cwd) == 0 then H.error('`source.cwd` should be a valid directory path.') end + + source.match = source.match or MiniPick.default_match + validate_callable(source.match, 'source.match') + + source.show = source.show or MiniPick.default_show + validate_callable(source.show, 'source.show') + + source.preview = source.preview or MiniPick.default_preview + validate_callable(source.preview, 'source.preview') + + source.choose = source.choose or MiniPick.default_choose + validate_callable(source.choose, 'source.choose') + + source.choose_marked = source.choose_marked or MiniPick.default_choose_marked + validate_callable(source.choose_marked, 'source.choose_marked') + + -- Delay + for key, value in pairs(opts.delay) do + local is_valid_value = type(value) == 'number' and value > 0 + if not is_valid_value then H.error(string.format('`delay.%s` should be a positive number.', key)) end + end + + -- Mappings + local default_mappings = H.default_config.mappings + for field, x in pairs(opts.mappings) do + if type(field) ~= 'string' then H.error('`mappings` should have only string fields.') end + local is_builtin_action = default_mappings[field] ~= nil + if is_builtin_action and type(x) ~= 'string' then + H.error(string.format('Mapping for built-in action "%s" should be string.', field)) + end + if not is_builtin_action and not (type(x) == 'table' and type(x.char) == 'string' and vim.is_callable(x.func)) then + H.error(string.format('Mapping for custom action "%s" should be table with `char` and `func`.', field)) + end + end + + -- Options + local options = opts.options + if type(options.content_from_bottom) ~= 'boolean' then H.error('`options.content_from_bottom` should be boolean.') end + if type(options.use_cache) ~= 'boolean' then H.error('`options.use_cache` should be boolean.') end + + -- Window + local win_config = opts.window.config + local is_valid_winconfig = win_config == nil or type(win_config) == 'table' or vim.is_callable(win_config) + if not is_valid_winconfig then H.error('`window.config` should be table or callable.') end + + return opts +end + +H.picker_new = function(opts) + -- Create buffer + local buf_id = H.picker_new_buf() + + -- Create window + local win_target = vim.api.nvim_get_current_win() + local win_id = H.picker_new_win(buf_id, opts.window.config) + + -- Constuct and return object + local picker = { + -- Permanent data about picker (should not change) + opts = opts, + + -- Items to pick from + items = nil, + stritems = nil, + stritems_ignorecase = nil, + + -- Associated Neovim objects + buffers = { main = buf_id, preview = nil, info = nil }, + windows = { main = win_id, target = win_target }, + + -- Query data + query = {}, + -- - Query index at which new entry will be inserted + caret = 1, + -- - Array of `stritems` indexes matching current query + match_inds = nil, + -- - Map of of currently marked `stritems` indexes (as keys) + marked_inds_map = {}, + + -- Whether picker is currently busy processing data + is_busy = false, + + -- Cache for `matches` per prompt for more performant querying + cache = {}, + + -- View data + -- - Which buffer should currently be shown + view_state = 'main', + + -- - Index range of `match_inds` currently visible. Present for significant + -- performance increase to render only what is visible. + visible_range = { from = nil, to = nil }, + + -- - Index of `match_inds` pointing at current item + current_ind = nil, + } + + H.querytick = H.querytick + 1 + + return picker +end + +H.picker_advance = function(picker) + vim.schedule(function() vim.api.nvim_exec_autocmds('User', { pattern = 'MiniPickStart' }) end) + + local char_data = H.picker_get_char_data(picker) + + local do_match, is_aborted = false, false + for _ = 1, 1000000 do + if H.cache.is_force_stop_advance then break end + H.picker_update(picker, do_match) + + local char = H.getcharstr(picker.opts.delay.async) + if H.cache.is_force_stop_advance then break end + + is_aborted = char == nil + if is_aborted then break end + + local cur_data = char_data[char] or {} + do_match = cur_data.name == nil or vim.startswith(cur_data.name, 'delete') or cur_data.name == 'paste' + is_aborted = cur_data.name == 'stop' + + local should_stop + if cur_data.is_custom then + should_stop = cur_data.func() + else + should_stop = (cur_data.func or H.picker_query_add)(picker, char) + end + if should_stop then break end + end + + local item + if not is_aborted then item = H.picker_get_current_item(picker) end + H.cache.is_force_stop_advance = nil + H.picker_stop(picker) + return item +end + +H.picker_update = function(picker, do_match, update_window) + if do_match then H.picker_match(picker) end + if update_window then + local config = H.picker_compute_win_config(picker.opts.window.config) + vim.api.nvim_win_set_config(picker.windows.main, config) + H.picker_set_current_ind(picker, picker.current_ind, true) + end + H.picker_set_bordertext(picker) + H.picker_set_lines(picker) + H.redraw() +end + +H.picker_new_buf = function() + local buf_id = H.create_scratch_buf() + vim.bo[buf_id].filetype = 'minipick' + return buf_id +end + +H.picker_new_win = function(buf_id, win_config) + -- Create window and focus on it. Focus cursor on Command line to not see it. + local win_id = vim.api.nvim_open_win(buf_id, true, H.picker_compute_win_config(win_config, true)) + if vim.fn.mode() == 'n' then vim.cmd('noautocmd normal! :') end + + -- Set window-local data + vim.wo[win_id].foldenable = false + vim.wo[win_id].list = true + vim.wo[win_id].listchars = 'extends:…' + vim.wo[win_id].scrolloff = 0 + vim.wo[win_id].wrap = false + H.win_update_hl(win_id, 'NormalFloat', 'MiniPickNormal') + H.win_update_hl(win_id, 'FloatBorder', 'MiniPickBorder') + + return win_id +end + +H.picker_compute_win_config = function(win_config, is_for_open) + local has_tabline = vim.o.showtabline == 2 or (vim.o.showtabline == 1 and #vim.api.nvim_list_tabpages() > 1) + local has_statusline = vim.o.laststatus > 0 + local max_height = vim.o.lines - vim.o.cmdheight - (has_tabline and 1 or 0) - (has_statusline and 1 or 0) + local max_width = vim.o.columns + + local default_config = { + relative = 'editor', + anchor = 'SW', + width = math.floor(0.618 * max_width), + height = math.floor(0.618 * max_height), + col = 0, + row = max_height + (has_tabline and 1 or 0), + border = 'single', + style = 'minimal', + noautocmd = is_for_open, + } + local config = vim.tbl_deep_extend('force', default_config, H.expand_callable(win_config) or {}) + + -- Tweak config values to ensure they are proper + if config.border == 'none' then config.border = { '', ' ', '', '', '', ' ', '', '' } end + -- - Account for border + config.height = math.min(config.height, max_height - 2) + config.width = math.min(config.width, max_width - 2) + + return config +end + +H.picker_track_lost_focus = function(picker) + local stop_timer = vim.schedule_wrap(function() H.timers.focus:stop() end) + vim.api.nvim_create_autocmd('User', { once = true, pattern = 'MiniPickStop', callback = stop_timer }) + + local track = vim.schedule_wrap(function() + local is_cur_win = vim.api.nvim_get_current_win() == picker.windows.main + local is_proper_focus = is_cur_win and (H.cache.is_in_getcharstr or vim.fn.mode() ~= 'n') + if is_proper_focus then return end + H.picker_stop(picker, true) + stop_timer() + end) + H.timers.focus:start(1000, 1000, track) +end + +H.picker_set_items = function(picker, items, opts) + -- Compute string items to work with (along with their lower variants) + local stritems, stritems_ignorecase, tolower = {}, {}, H.tolower + local poke_picker = H.poke_picker_throttle(opts.querytick) + for i, x in ipairs(items) do + if not poke_picker() then return end + local to_add = H.item_to_string(x) + table.insert(stritems, to_add) + table.insert(stritems_ignorecase, tolower(to_add)) + end + + picker.items, picker.stritems, picker.stritems_ignorecase = items, stritems, stritems_ignorecase + picker.cache, picker.marked_inds_map = {}, {} + H.picker_set_busy(picker, false) + + H.picker_set_match_inds(picker, H.seq_along(items)) + H.picker_update(picker, opts.do_match) +end + +H.item_to_string = function(item) + item = H.expand_callable(item) + if type(item) == 'string' then return item end + if type(item) == 'table' and type(item.text) == 'string' then return item.text end + return vim.inspect(item, { newline = ' ', indent = '' }) +end + +H.picker_set_busy = function(picker, value) + picker.is_busy = value + + -- NOTE: Don't precompute highlight group to always set valid one + local update_border_hl = function() + H.win_update_hl(picker.windows.main, 'FloatBorder', picker.is_busy and 'MiniPickBorderBusy' or 'MiniPickBorder') + end + + if value then + H.timers.busy:start(picker.opts.delay.busy, 0, vim.schedule_wrap(update_border_hl)) + else + H.timers.busy:stop() + update_border_hl() + end +end + +H.picker_set_match_inds = function(picker, inds) + if inds == nil then return end + H.picker_set_busy(picker, false) + + picker.match_inds = inds + + local cache_prompt = table.concat(picker.query) + if picker.opts.options.use_cache then picker.cache[cache_prompt] = { inds = inds } end + + -- Always show result of updated matches + H.picker_show_main(picker) + + -- Reset current index if match indexes are updated + H.picker_set_current_ind(picker, 1) +end + +H.picker_set_current_ind = function(picker, ind, force_update) + if picker.items == nil or #picker.match_inds == 0 then + picker.current_ind, picker.visible_range = nil, {} + return + end + + -- Wrap index around edges + local n_matches = #picker.match_inds + ind = (ind - 1) % n_matches + 1 + + -- (Re)Compute visible range (centers current index if it is currently outside) + local from, to, querytick = picker.visible_range.from, picker.visible_range.to, picker.visible_range.querytick + local needs_update = H.querytick ~= querytick or from == nil or to == nil or not (from <= ind and ind <= to) + if (force_update or needs_update) and H.is_valid_win(picker.windows.main) then + local win_height = vim.api.nvim_win_get_height(picker.windows.main) + to = math.min(n_matches, math.floor(ind + 0.5 * win_height)) + from = math.max(1, to - win_height + 1) + to = from + math.min(win_height, n_matches) - 1 + end + + -- Set data + picker.current_ind = ind + picker.visible_range = { from = from, to = to, querytick = H.querytick } +end + +H.picker_set_lines = function(picker) + local buf_id, win_id = picker.buffers.main, picker.windows.main + if not (H.is_valid_buf(buf_id) and H.is_valid_win(win_id)) then return end + + if picker.is_busy then return end + + local visible_range, query = picker.visible_range, picker.query + if picker.items == nil or visible_range.from == nil or visible_range.to == nil then + picker.opts.source.show(buf_id, {}, query) + H.clear_namespace(buf_id, H.ns_id.matches) + return + end + + -- Construct target items + local items_to_show, items, match_inds = {}, picker.items, picker.match_inds + local cur_ind, cur_line = picker.current_ind, nil + local marked_inds_map, marked_lnums = picker.marked_inds_map, {} + local is_from_bottom = picker.opts.options.content_from_bottom + local from = is_from_bottom and visible_range.to or visible_range.from + local to = is_from_bottom and visible_range.from or visible_range.to + for i = from, to, (from <= to and 1 or -1) do + table.insert(items_to_show, items[match_inds[i]]) + if i == cur_ind then cur_line = #items_to_show end + if marked_inds_map[match_inds[i]] then table.insert(marked_lnums, #items_to_show) end + end + + local n_empty_top_lines = is_from_bottom and (vim.api.nvim_win_get_height(win_id) - #items_to_show) or 0 + cur_line = cur_line + n_empty_top_lines + marked_lnums = vim.tbl_map(function(x) return x + n_empty_top_lines end, marked_lnums) + + -- Update visible lines accounting for "from_bottom" direction + picker.opts.source.show(buf_id, items_to_show, query) + if n_empty_top_lines > 0 then + local empty_lines = vim.fn['repeat']({ '' }, n_empty_top_lines) + vim.api.nvim_buf_set_lines(buf_id, 0, 0, true, empty_lines) + end + + local ns_id = H.ns_id.matches + H.clear_namespace(buf_id, ns_id) + + -- Add highlighting for marked lines + local marked_opts = { end_col = 0, hl_group = 'MiniPickMatchMarked', priority = 202 } + for _, lnum in ipairs(marked_lnums) do + marked_opts.end_row = lnum + H.set_extmark(buf_id, ns_id, lnum - 1, 0, marked_opts) + end + + -- Update current item + if cur_line > vim.api.nvim_buf_line_count(buf_id) then return end + + local cur_opts = { end_row = cur_line, end_col = 0, hl_eol = true, hl_group = 'MiniPickMatchCurrent', priority = 201 } + H.set_extmark(buf_id, ns_id, cur_line - 1, 0, cur_opts) + + -- - Update cursor if showing item matches (needed for 'scroll_{left,right}') + local cursor = vim.api.nvim_win_get_cursor(win_id) + if picker.view_state == 'main' and cursor[1] ~= cur_line then H.set_cursor(win_id, cur_line, cursor[2] + 1) end +end + +H.picker_match = function(picker) + if picker.items == nil then return end + + -- Try to use cache first + local prompt_cache + if picker.opts.options.use_cache then prompt_cache = picker.cache[table.concat(picker.query)] end + if prompt_cache ~= nil then return H.picker_set_match_inds(picker, prompt_cache.inds) end + + local is_ignorecase = H.query_is_ignorecase(picker.query) + local stritems = is_ignorecase and picker.stritems_ignorecase or picker.stritems + local query = is_ignorecase and vim.tbl_map(H.tolower, picker.query) or picker.query + + H.picker_set_busy(picker, true) + local new_inds = picker.opts.source.match(stritems, picker.match_inds, query) + H.picker_set_match_inds(picker, new_inds) +end + +H.query_is_ignorecase = function(query) + if not vim.o.ignorecase then return false end + if not vim.o.smartcase then return true end + return vim.fn.match(table.concat(query), '[[:upper:]]') < 0 +end + +H.picker_get_char_data = function(picker, skip_alternatives) + local term = H.replace_termcodes + local res = {} + + -- Use alternative keys for some common actions + local alt_chars = {} + if not skip_alternatives then alt_chars = { move_down = '', move_start = '', move_up = '' } end + + -- Process + for name, rhs in pairs(picker.opts.mappings) do + local is_custom = type(rhs) == 'table' + local char = is_custom and rhs.char or rhs + local data = { char = char, name = name, func = is_custom and rhs.func or H.actions[name], is_custom = is_custom } + res[term(char)] = data + + local alt = alt_chars[name] + if alt ~= nil then res[term(alt)] = data end + end + + return res +end + +H.picker_set_bordertext = function(picker) + local win_id = picker.windows.main + if not H.is_valid_win(win_id) then return end + + -- Compute main text managing views separately and truncating from left + local view_state = picker.view_state + local config + if view_state == 'main' then + local query, caret = picker.query, picker.caret + local before_caret = table.concat(vim.list_slice(query, 1, caret - 1), '') + local after_caret = table.concat(vim.list_slice(query, caret, #query), '') + local prompt_text = '> ' .. before_caret .. '▏' .. after_caret + local prompt = { { H.win_trim_to_width(win_id, prompt_text), 'MiniPickPrompt' } } + config = { title = prompt } + end + + local has_items = picker.items ~= nil + if view_state == 'preview' and has_items then + local stritem_cur = picker.stritems[picker.match_inds[picker.current_ind]] or '' + -- Sanitize title + stritem_cur = stritem_cur:gsub('[%s%z]', ' ') + config = { title = { { H.win_trim_to_width(win_id, stritem_cur), 'MiniPickBorderText' } } } + end + + if view_state == 'info' then + config = { title = { { H.win_trim_to_width(win_id, 'Info'), 'MiniPickBorderText' } } } + end + + -- Compute helper footer only if Neovim version permits and not in busy + -- picker (otherwise it will flicker number of matches data on char delete) + local nvim_has_window_footer = vim.fn.has('nvim-0.10') == 1 + if nvim_has_window_footer and not picker.is_busy then + config.footer, config.footer_pos = H.picker_compute_footer(picker, win_id), 'left' + end + + -- Respect `options.content_from_bottom` + if nvim_has_window_footer and picker.opts.options.content_from_bottom then + config.title, config.footer = config.footer, config.title + end + + vim.api.nvim_win_set_config(win_id, config) + vim.wo[win_id].list = true +end + +-- - No border text functionality is available in Neovim<0.9 +if vim.fn.has('nvim-0.9') == 0 then H.picker_set_bordertext = function() end end + +H.picker_compute_footer = function(picker, win_id) + local info = H.picker_get_general_info(picker) + local source_name = string.format(' %s ', info.source_name) + local n_marked_text = info.n_marked == 0 and '' or (info.n_marked .. '/') + local inds = string.format(' %s|%s|%s%s ', info.relative_current_ind, info.n_matched, n_marked_text, info.n_total) + local win_width, source_width, inds_width = + vim.api.nvim_win_get_width(win_id), vim.fn.strchars(source_name), vim.fn.strchars(inds) + + local footer = { { source_name, 'MiniPickBorderText' } } + local n_spaces_between = win_width - (source_width + inds_width) + if n_spaces_between > 0 then + local border_hl = picker.is_busy and 'MiniPickBorderBusy' or 'MiniPickBorder' + footer[2] = { H.win_get_bottom_border(win_id):rep(n_spaces_between), border_hl } + footer[3] = { inds, 'MiniPickBorderText' } + end + return footer +end + +H.picker_stop = function(picker, abort) + if picker == nil then return end + + vim.api.nvim_exec_autocmds('User', { pattern = 'MiniPickStop' }) + + if abort then + H.pickers = {} + else + local new_latest = vim.deepcopy(picker) + H.picker_free(H.pickers.latest) + H.pickers = { active = nil, latest = new_latest } + end + + H.set_curwin(picker.windows.target) + pcall(vim.api.nvim_win_close, picker.windows.main, true) + pcall(vim.api.nvim_buf_delete, picker.buffers.main, { force = true }) + pcall(vim.api.nvim_buf_delete, picker.buffers.info, { force = true }) + picker.windows, picker.buffers = {}, {} + + H.querytick = H.querytick + 1 +end + +H.picker_free = function(picker) + if picker == nil then return end + picker.match_inds = nil + picker.cache = nil + picker.stritems, picker.stritems_ignorecase, picker.marked_inds_map = nil, nil, nil + picker.items = nil + picker = nil + vim.schedule(function() collectgarbage('collect') end) +end + +--stylua: ignore +H.actions = { + caret_left = function(picker, _) H.picker_move_caret(picker, -1) end, + caret_right = function(picker, _) H.picker_move_caret(picker, 1) end, + + choose = function(picker, _) return H.picker_choose(picker, nil) end, + choose_in_split = function(picker, _) return H.picker_choose(picker, 'split') end, + choose_in_tabpage = function(picker, _) return H.picker_choose(picker, 'tabnew') end, + choose_in_vsplit = function(picker, _) return H.picker_choose(picker, 'vsplit') end, + choose_marked = function(picker, _) return not picker.opts.source.choose_marked(MiniPick.get_picker_matches().marked) end, + + delete_char = function(picker, _) H.picker_query_delete(picker, 1) end, + delete_char_right = function(picker, _) H.picker_query_delete(picker, 0) end, + delete_left = function(picker, _) H.picker_query_delete(picker, picker.caret - 1) end, + delete_word = function(picker, _) + local init, n_del = picker.caret - 1, 0 + if init == 0 then return end + local ref_is_keyword = vim.fn.match(picker.query[init], '[[:keyword:]]') >= 0 + for i = init, 1, -1 do + local cur_is_keyword = vim.fn.match(picker.query[i], '[[:keyword:]]') >= 0 + if (ref_is_keyword and not cur_is_keyword) or (not ref_is_keyword and cur_is_keyword) then break end + n_del = n_del + 1 + end + H.picker_query_delete(picker, n_del) + end, + + mark = function(picker, _) H.picker_mark_indexes(picker, 'current') end, + mark_all = function(picker, _) H.picker_mark_indexes(picker, 'all') end, + + move_down = function(picker, _) H.picker_move_current(picker, 1) end, + move_start = function(picker, _) H.picker_move_current(picker, nil, 1) end, + move_up = function(picker, _) H.picker_move_current(picker, -1) end, + + paste = function(picker, _) + local register = H.getcharstr(picker.opts.delay.async) + local has_register, reg_contents = pcall(vim.fn.getreg, register) + if not has_register then return end + reg_contents = reg_contents:gsub('[\n\t]', ' ') + for i = 1, vim.fn.strchars(reg_contents) do + H.picker_query_add(picker, vim.fn.strcharpart(reg_contents, i - 1, 1)) + end + end, + + refine = function(picker, _) H.picker_refine(picker, 'all') end, + refine_marked = function(picker, _) H.picker_refine(picker, 'marked') end, + + scroll_down = function(picker, _) H.picker_scroll(picker, 'down') end, + scroll_up = function(picker, _) H.picker_scroll(picker, 'up') end, + scroll_left = function(picker, _) H.picker_scroll(picker, 'left') end, + scroll_right = function(picker, _) H.picker_scroll(picker, 'right') end, + + toggle_info = function(picker, _) + if picker.view_state == 'info' then return H.picker_show_main(picker) end + H.picker_show_info(picker) + end, + + toggle_preview = function(picker, _) + if picker.view_state == 'preview' then return H.picker_show_main(picker) end + H.picker_show_preview(picker) + end, + + stop = function(_, _) return true end, +} + +H.picker_query_add = function(picker, char) + -- Determine if it **is** proper single character + if vim.fn.strchars(char) > 1 or vim.fn.char2nr(char) <= 31 then return end + table.insert(picker.query, picker.caret, char) + picker.caret = picker.caret + 1 + H.querytick = H.querytick + 1 + + -- Adding character inside query might not result into narrowing matches, so + -- reset match indexes. Use cache to speed this up. + local should_reset = picker.items ~= nil and picker.caret <= #picker.query + if should_reset then picker.match_inds = H.seq_along(picker.items) end +end + +H.picker_query_delete = function(picker, n) + local delete_to_left = n > 0 + local left = delete_to_left and math.max(picker.caret - n, 1) or picker.caret + local right = delete_to_left and picker.caret - 1 or math.min(picker.caret + n, #picker.query) + for i = right, left, -1 do + table.remove(picker.query, i) + end + picker.caret = left + H.querytick = H.querytick + 1 + + -- Deleting query character increases number of possible matches, so need to + -- reset already matched indexes prior deleting. Use cache to speed this up. + if picker.items ~= nil then picker.match_inds = H.seq_along(picker.items) end +end + +H.picker_choose = function(picker, pre_command) + local cur_item = H.picker_get_current_item(picker) + if cur_item == nil then return true end + + local win_id_target = picker.windows.target + if pre_command ~= nil and H.is_valid_win(win_id_target) then + vim.api.nvim_win_call(win_id_target, function() + vim.cmd(pre_command) + picker.windows.target = vim.api.nvim_get_current_win() + end) + end + + -- Returning nothing, `nil`, or `false` should lead to picker stop + return not picker.opts.source.choose(cur_item) +end + +H.picker_mark_indexes = function(picker, range_type) + if picker.items == nil then return end + local test_inds = range_type == 'current' and { picker.match_inds[picker.current_ind] } or picker.match_inds + + -- Mark if not all marked, unmark otherwise + local marked_inds_map, is_all_marked = picker.marked_inds_map, true + for _, ind in ipairs(test_inds) do + is_all_marked = is_all_marked and marked_inds_map[ind] + end + + -- NOTE: Set to `nil` and not `false` for easier counting of present values + local new_val + if not is_all_marked then new_val = true end + for _, ind in ipairs(test_inds) do + marked_inds_map[ind] = new_val + end + + if picker.view_state == 'info' then H.picker_show_info(picker) end +end + +H.picker_move_caret = function(picker, n) picker.caret = math.min(math.max(picker.caret + n, 1), #picker.query + 1) end + +H.picker_move_current = function(picker, by, to) + if picker.items == nil then return end + local n_matches = #picker.match_inds + if n_matches == 0 then return end + + if to == nil then + -- Account for content direction + by = (picker.opts.options.content_from_bottom and -1 or 1) * by + + -- Wrap around edges only if current index is at edge + to = picker.current_ind + if to == 1 and by < 0 then + to = n_matches + elseif to == n_matches and by > 0 then + to = 1 + else + to = to + by + end + to = math.min(math.max(to, 1), n_matches) + end + + H.picker_set_current_ind(picker, to) + + -- Update not main buffer(s) + if picker.view_state == 'info' then H.picker_show_info(picker) end + if picker.view_state == 'preview' then H.picker_show_preview(picker) end +end + +H.picker_refine = function(picker, refine_type) + if picker.items == nil then return end + + -- Make current matches be new items to be matched with default match + picker.opts.source.match = H.get_config().source.match or MiniPick.default_match + picker.query, picker.caret = {}, 1 + MiniPick.set_picker_items(MiniPick.get_picker_matches()[refine_type] or {}) + + picker._refine = picker._refine or { orig_name = picker.opts.source.name, count = 0 } + picker._refine.count = picker._refine.count + 1 + local count_suffix = picker._refine.count == 1 and '' or (' ' .. picker._refine.count) + picker.opts.source.name = string.format('%s (Refine%s)', picker._refine.orig_name, count_suffix) +end + +H.picker_scroll = function(picker, direction) + local win_id = picker.windows.main + if picker.view_state == 'main' and (direction == 'down' or direction == 'up') then + local n = (direction == 'down' and 1 or -1) * vim.api.nvim_win_get_height(win_id) + H.picker_move_current(picker, n) + else + local keys = ({ down = '', up = '', left = 'zH', right = 'zL' })[direction] + vim.api.nvim_win_call(win_id, function() vim.cmd('normal! ' .. H.replace_termcodes(keys)) end) + end +end + +H.picker_get_current_item = function(picker) + if picker.items == nil then return nil end + return picker.items[picker.match_inds[picker.current_ind]] +end + +H.picker_show_main = function(picker) + H.set_winbuf(picker.windows.main, picker.buffers.main) + picker.view_state = 'main' +end + +H.picker_show_info = function(picker) + -- General information + local info = H.picker_get_general_info(picker) + local lines = { + 'General', + 'Source name │ ' .. info.source_name, + 'Source cwd │ ' .. info.source_cwd, + 'Total items │ ' .. info.n_total, + 'Matched items │ ' .. info.n_matched, + 'Marked items │ ' .. info.n_marked, + 'Current index │ ' .. info.relative_current_ind, + } + local hl_lines = { 1 } + + local append_char_data = function(data, header) + if #data == 0 then return end + table.insert(lines, '') + table.insert(lines, header) + table.insert(hl_lines, #lines) + + local width_max = 0 + for _, t in ipairs(data) do + local desc = t.name:gsub('[%s%p]', ' ') + t.desc = vim.fn.toupper(desc:sub(1, 1)) .. desc:sub(2) + t.width = vim.fn.strchars(t.desc) + width_max = math.max(width_max, t.width) + end + table.sort(data, function(a, b) return a.desc < b.desc end) + + for _, t in ipairs(data) do + table.insert(lines, string.format('%s%s │ %s', t.desc, string.rep(' ', width_max - t.width), t.char)) + end + end + + local char_data = H.picker_get_char_data(picker, true) + append_char_data(vim.tbl_filter(function(x) return x.is_custom end, char_data), 'Mappings (custom)') + append_char_data(vim.tbl_filter(function(x) return not x.is_custom end, char_data), 'Mappings (built-in)') + + -- Manage buffer/window/state + local buf_id_info = picker.buffers.info + if not H.is_valid_buf(buf_id_info) then buf_id_info = H.create_scratch_buf() end + picker.buffers.info = buf_id_info + + H.set_buflines(buf_id_info, lines) + H.set_winbuf(picker.windows.main, buf_id_info) + picker.view_state = 'info' + + local ns_id = H.ns_id.headers + H.clear_namespace(buf_id_info, ns_id) + for _, lnum in ipairs(hl_lines) do + H.set_extmark(buf_id_info, ns_id, lnum - 1, 0, { end_row = lnum, end_col = 0, hl_group = 'MiniPickHeader' }) + end +end + +H.picker_get_general_info = function(picker) + local has_items = picker.items ~= nil + return { + source_name = picker.opts.source.name or '---', + source_cwd = vim.fn.fnamemodify(picker.opts.source.cwd, ':~') or '---', + n_total = has_items and #picker.items or '-', + n_matched = has_items and #picker.match_inds or '-', + n_marked = has_items and vim.tbl_count(picker.marked_inds_map) or '-', + relative_current_ind = has_items and picker.current_ind or '-', + } +end + +H.picker_show_preview = function(picker) + local preview = picker.opts.source.preview + local item = H.picker_get_current_item(picker) + if item == nil then return end + + local win_id, buf_id = picker.windows.main, H.create_scratch_buf() + vim.bo[buf_id].bufhidden = 'wipe' + H.set_winbuf(win_id, buf_id) + preview(buf_id, item) + picker.buffers.preview = buf_id + picker.view_state = 'preview' +end + +-- Default match -------------------------------------------------------------- +H.match_filter = function(inds, stritems, query) + -- 'abc' and '*abc' - fuzzy; "'abc" and 'a' - exact substring; + -- 'ab c' - grouped fuzzy; '^abc' and 'abc$' - exact substring at start/end. + local is_fuzzy_forced, is_exact_plain, is_exact_start, is_exact_end = + query[1] == '*', query[1] == "'", query[1] == '^', query[#query] == '$' + local is_grouped, grouped_parts = H.match_query_group(query) + + if is_fuzzy_forced or is_exact_plain or is_exact_start or is_exact_end then + local start_offset = (is_fuzzy_forced or is_exact_plain or is_exact_start) and 2 or 1 + local end_offset = #query - ((not is_fuzzy_forced and not is_exact_plain and is_exact_end) and 1 or 0) + query = vim.list_slice(query, start_offset, end_offset) + elseif is_grouped then + query = grouped_parts + end + + if #query == 0 then return {}, 'nosort', query end + + local is_fuzzy_plain = not (is_exact_plain or is_exact_start or is_exact_end) and #query > 1 + if is_fuzzy_forced or is_fuzzy_plain then return H.match_filter_fuzzy(inds, stritems, query), 'fuzzy', query end + + local prefix = is_exact_start and '^' or '' + local suffix = is_exact_end and '$' or '' + local pattern = prefix .. vim.pesc(table.concat(query)) .. suffix + + return H.match_filter_exact(inds, stritems, query, pattern), 'exact', query +end + +H.match_filter_exact = function(inds, stritems, query, pattern) + local match_single = H.match_filter_exact_single + local poke_picker = H.poke_picker_throttle(H.querytick) + local match_data = {} + for _, ind in ipairs(inds) do + if not poke_picker() then return nil end + local data = match_single(stritems[ind], ind, pattern) + if data ~= nil then table.insert(match_data, data) end + end + + return match_data +end + +H.match_filter_exact_single = function(candidate, index, pattern) + local start = string.find(candidate, pattern) + if start == nil then return nil end + + return { 0, start, index } +end + +H.match_ranges_exact = function(match_data, query) + -- All matches have same match ranges relative to match start + local cur_start, rel_ranges = 0, {} + for i = 1, #query do + rel_ranges[i] = { cur_start, cur_start + query[i]:len() - 1 } + cur_start = rel_ranges[i][2] + 1 + end + + local res = {} + for i = 1, #match_data do + local start = match_data[i][2] + res[i] = vim.tbl_map(function(x) return { start + x[1], start + x[2] } end, rel_ranges) + end + + return res +end + +H.match_filter_fuzzy = function(inds, stritems, query) + local match_single, find_query = H.match_filter_fuzzy_single, H.match_find_query + local poke_picker = H.poke_picker_throttle(H.querytick) + local match_data = {} + for _, ind in ipairs(inds) do + if not poke_picker() then return nil end + local data = match_single(stritems[ind], ind, query, find_query) + if data ~= nil then table.insert(match_data, data) end + end + return match_data +end + +H.match_filter_fuzzy_single = function(candidate, index, query, find_query) + -- Search for query chars match positions with the following properties: + -- - All are present in `candidate` in the same order. + -- - Has smallest width among all such match positions. + -- - Among same width has smallest first match. + + -- Search forward to find matching positions with left-most last char match + local first, last = find_query(candidate, query, 1) + if first == nil then return nil end + if first == last then return { 0, first, index, { first } } end + + -- NOTE: This approach doesn't iterate **all** query matches. It is fine for + -- width optimization but maybe not for more (like contiguous groups number). + -- Example: for query {'a', 'b', 'c'} candidate 'aaxbbbc' will be matched as + -- having 3 groups (indexes 2, 4, 7) but correct one is 2 groups (2, 6, 7). + + -- Iteratively try to find better matches by advancing last match + local best_first, best_last, best_width = first, last, last - first + while last do + local width = last - first + if width < best_width then + best_first, best_last, best_width = first, last, width + end + + first, last = find_query(candidate, query, first + 1) + end + + -- NOTE: No field names is not clear code, but consistently better performant + return { best_last - best_first, best_first, index } +end + +H.match_ranges_fuzzy = function(match_data, query, stritems) + local res, n_query, query_lens = {}, #query, vim.tbl_map(string.len, query) + for i_match, data in ipairs(match_data) do + local s, from, to = stritems[data[3]], data[2], data[2] + query_lens[1] - 1 + local ranges = { { from, to } } + for j_query = 2, n_query do + from, to = string.find(s, query[j_query], to + 1, true) + ranges[j_query] = { from, to } + end + res[i_match] = ranges + end + return res +end + +H.match_find_query = function(s, query, init) + local first, to = string.find(s, query[1], init, true) + if first == nil then return nil, nil end + + -- Both `first` and `last` indicate the start byte of first and last match + local last = first + for i = 2, #query do + last, to = string.find(s, query[i], to + 1, true) + if not last then return nil, nil end + end + return first, last +end + +H.match_query_group = function(query) + local parts = { {} } + for _, x in ipairs(query) do + local is_whitespace = x:find('^%s+$') ~= nil + if is_whitespace then table.insert(parts, {}) end + if not is_whitespace then table.insert(parts[#parts], x) end + end + return #parts > 1, vim.tbl_map(table.concat, parts) +end + +H.match_sort = function(match_data) + -- Spread indexes in width-start buckets + local buckets, max_width, width_max_start = {}, 0, {} + for i = 1, #match_data do + local data, width, start = match_data[i], match_data[i][1], match_data[i][2] + local buck_width = buckets[width] or {} + local buck_start = buck_width[start] or {} + table.insert(buck_start, data[3]) + buck_width[start] = buck_start + buckets[width] = buck_width + + max_width = math.max(max_width, width) + width_max_start[width] = math.max(width_max_start[width] or 0, start) + end + + -- Sort index in place (to make stable sort) within buckets + local poke_picker = H.poke_picker_throttle(H.querytick) + for _, buck_width in pairs(buckets) do + for _, buck_start in pairs(buck_width) do + if not poke_picker() then return nil end + table.sort(buck_start) + end + end + + -- Gather indexes back in order + local res = {} + for width = 0, max_width do + local buck_width = buckets[width] + for start = 1, (width_max_start[width] or 0) do + local buck_start = buck_width[start] or {} + for i = 1, #buck_start do + table.insert(res, buck_start[i]) + end + end + end + + return res +end + +-- Default show --------------------------------------------------------------- +H.get_icon = function(x) + local path_type, path = H.parse_path(x) + if path_type == nil then return { text = '' } end + if path_type == 'directory' then return { text = ' ', hl = 'MiniPickIconDirectory' } end + if path_type == 'none' then return { text = ' ', hl = 'MiniPickNormal' } end + local has_devicons, devicons = pcall(require, 'nvim-web-devicons') + if not has_devicons then return { text = ' ', hl = 'MiniPickIconFile' } end + + local icon, hl = devicons.get_icon(vim.fn.fnamemodify(path, ':t'), nil, { default = false }) + return { text = (icon or '') .. ' ', hl = hl or 'MiniPickIconFile' } +end + +H.show_with_icons = + function(buf_id, items, query) MiniPick.default_show(buf_id, items, query, { show_icons = true }) end + +-- Items helpers for default functions ---------------------------------------- +H.parse_item = function(item) + -- Try parsing table item first + if type(item) == 'table' then return H.parse_item_table(item) end + + -- Parse item's string representation + local stritem = H.item_to_string(item) + + -- - Buffer + local ok, numitem = pcall(tonumber, stritem) + if ok and H.is_valid_buf(numitem) then return { type = 'buffer', buf_id = numitem } end + + -- File or Directory + local path_type, path, lnum, col, rest = H.parse_path(stritem) + if path_type ~= 'none' then return { type = path_type, path = path, lnum = lnum, col = col, text = rest } end + + return {} +end + +H.parse_item_table = function(item) + -- Buffer + local buf_id = item.bufnr or item.buf_id or item.buf + if H.is_valid_buf(buf_id) then + --stylua: ignore + return { + type = 'buffer', buf_id = buf_id, + lnum = item.lnum, end_lnum = item.end_lnum, + col = item.col, end_col = item.end_col, + text = item.text, + } + end + + -- File or Directory + if type(item.path) == 'string' then + local path_type, path, lnum, col, rest = H.parse_path(item.path) + if path_type == 'file' then + --stylua: ignore + return { + type = 'file', path = path, + lnum = lnum or item.lnum, end_lnum = item.end_lnum, + col = col or item.col, end_col = item.end_col, + text = rest ~= '' and rest or item.text, + } + end + + if path_type == 'directory' then return { type = 'directory', path = item.path } end + end + + return {} +end + +H.parse_path = function(x) + if type(x) ~= 'string' or x == '' then return nil end + -- Allow inputs like 'aa/bb', 'aa/bb:10', 'aa/bb:10:5', 'aa/bb:10:5:xxx' + -- Should also work for paths like 'aa-5' + local location_pattern = ':(%d+):?(%d*):?(.*)$' + local lnum, col, rest = x:match(location_pattern) + local path = x:gsub(location_pattern, '', 1) + + -- Verify that path is real + local path_type = H.get_fs_type(path) + if path_type == 'none' then + path = string.format('%s/%s', H.get_cwd(), path) + path_type = H.get_fs_type(path) + end + + return path_type, path, tonumber(lnum), tonumber(col), rest or '' +end + +H.get_cwd = function() + if H.pickers.active == nil then return vim.fn.getcwd() end + return H.pickers.active.opts.source.cwd +end + +H.get_fs_type = function(path) + if path:find('^~') then path = vim.loop.os_homedir() .. path:sub(2) end + if vim.fn.filereadable(path) == 1 then return 'file' end + if vim.fn.isdirectory(path) == 1 then return 'directory' end + return 'none' +end + +-- Default preview ------------------------------------------------------------ +H.preview_file = function(buf_id, item_data, opts) + -- Fully preview only text files + if not H.is_file_text(item_data.path) then return H.set_buflines(buf_id, { '-Non-text-file-' }) end + + -- Compute lines. Limit number of read lines to work better on large files. + local has_lines, lines = pcall(vim.fn.readfile, item_data.path, '', (item_data.lnum or 1) + opts.n_context_lines) + if not has_lines then return end + + item_data.line_position = opts.line_position + H.preview_set_lines(buf_id, lines, item_data) +end + +H.preview_directory = function(buf_id, item_data) + local path = item_data.path + local format = function(x) return x .. (vim.fn.isdirectory(path .. '/' .. x) == 1 and '/' or '') end + local lines = vim.tbl_map(format, vim.fn.readdir(path)) + H.set_buflines(buf_id, lines) +end + +H.preview_buffer = function(buf_id, item_data, opts) + -- NOTE: ideally just setting target buffer to window would be enough, but it + -- has side effects. See https://github.com/neovim/neovim/issues/24973 . + -- Reading lines and applying custom styling is a passable alternative. + local buf_id_source = item_data.buf_id + + -- Get lines from buffer ensuring it is loaded without important consequences + local cache_eventignore = vim.o.eventignore + vim.o.eventignore = 'BufEnter' + vim.fn.bufload(buf_id_source) + vim.o.eventignore = cache_eventignore + local lines = vim.api.nvim_buf_get_lines(buf_id_source, 0, (item_data.lnum or 1) + opts.n_context_lines, false) + + item_data.filetype, item_data.line_position = vim.bo[buf_id_source].filetype, opts.line_position + H.preview_set_lines(buf_id, lines, item_data) +end + +H.preview_inspect = function(buf_id, obj) H.set_buflines(buf_id, vim.split(vim.inspect(obj), '\n')) end + +H.preview_set_lines = function(buf_id, lines, extra) + -- Lines + H.set_buflines(buf_id, lines) + + -- Highlighting + H.preview_highlight_region(buf_id, extra.lnum, extra.col, extra.end_lnum, extra.end_col) + + if vim.fn.has('nvim-0.8') == 1 then + local ft = extra.filetype or vim.filetype.match({ buf = buf_id, filename = extra.path }) + local has_lang, lang = pcall(vim.treesitter.language.get_lang, ft) + local has_ts, _ = pcall(vim.treesitter.start, buf_id, has_lang and lang or ft) + if not has_ts then vim.bo[buf_id].syntax = ft end + end + + -- Cursor position and window view + local state = MiniPick.get_picker_state() + local win_id = state ~= nil and state.windows.main or vim.fn.bufwinid(buf_id) + H.set_cursor(win_id, extra.lnum, extra.col) + local pos_keys = ({ top = 'zt', center = 'zz', bottom = 'zb' })[extra.line_position] or 'zt' + pcall(vim.api.nvim_win_call, win_id, function() vim.cmd('normal! ' .. pos_keys) end) +end + +H.preview_highlight_region = function(buf_id, lnum, col, end_lnum, end_col) + -- Highlight line + if lnum == nil then return end + local hl_line_opts = { end_row = lnum, end_col = 0, hl_eol = true, hl_group = 'MiniPickPreviewLine', priority = 201 } + H.set_extmark(buf_id, H.ns_id.preview, lnum - 1, 0, hl_line_opts) + + -- Highlight position/region + if col == nil then return end + + local ext_end_row, ext_end_col = lnum - 1, col + if end_lnum ~= nil and end_col ~= nil then + ext_end_row, ext_end_col = end_lnum - 1, end_col - 1 + end + ext_end_col = H.get_next_char_bytecol(vim.fn.getbufline(buf_id, ext_end_row + 1)[1], ext_end_col) + + local hl_region_opts = { end_row = ext_end_row, end_col = ext_end_col, priority = 202 } + hl_region_opts.hl_group = 'MiniPickPreviewRegion' + H.set_extmark(buf_id, H.ns_id.preview, lnum - 1, col - 1, hl_region_opts) +end + +-- Default choose ------------------------------------------------------------- +H.choose_path = function(win_target, item_data) + -- Try to use already created buffer, if present. This avoids not needed + -- `:edit` call and avoids some problems with auto-root from 'mini.misc'. + local path, path_buf_id = item_data.path, nil + for _, buf_id in ipairs(vim.api.nvim_list_bufs()) do + local is_target = H.is_valid_buf(buf_id) and vim.bo[buf_id].buflisted and vim.api.nvim_buf_get_name(buf_id) == path + if is_target then path_buf_id = buf_id end + end + + -- Set buffer in target window + if path_buf_id ~= nil then + H.set_winbuf(win_target, path_buf_id) + else + -- Use `pcall()` to avoid possible `:edit` errors, like present swap file + vim.api.nvim_win_call(win_target, function() pcall(vim.cmd, 'edit ' .. vim.fn.fnameescape(path)) end) + end + + H.choose_set_cursor(win_target, item_data.lnum, item_data.col) +end + +H.choose_buffer = function(win_target, item_data) + H.set_winbuf(win_target, item_data.buf_id) + H.choose_set_cursor(win_target, item_data.lnum, item_data.col) +end + +H.choose_print = function(x) print(vim.inspect(x)) end + +H.choose_set_cursor = function(win_id, lnum, col) + if lnum == nil then return end + H.set_cursor(win_id, lnum, col) + pcall(vim.api.nvim_win_call, win_id, function() vim.cmd('normal! zvzz') end) +end + +-- Builtins ------------------------------------------------------------------- +H.cli_postprocess = function(items) + while items[#items] == '' do + items[#items] = nil + end + return items +end + +H.is_executable = function(tool) + if tool == 'fallback' then return true end + return vim.fn.executable(tool) == 1 +end + +H.files_get_tool = function() + if H.is_executable('rg') then return 'rg' end + if H.is_executable('fd') then return 'fd' end + if H.is_executable('git') then return 'git' end + return 'fallback' +end + +H.files_get_command = function(tool) + if tool == 'rg' then return { 'rg', '--files', '--hidden', '--no-follow', '--color=never', '-g', '!.git' } end + if tool == 'fd' then return { 'fd', '--type=f', '--hidden', '--no-follow', '--color=never', '--exclude=.git' } end + if tool == 'git' then return { 'git', 'ls-files', '--cached', '--others', '--exclude-standard' } end + H.error([[Wrong 'tool' for `files` builtin.]]) +end + +H.files_fallback_items = function(cwd) + if vim.fn.has('nvim-0.9') == 0 then H.error('Tool "fallback" of `files` builtin needs Neovim>=0.9.') end + cwd = cwd or '.' + local poke_picker = H.poke_picker_throttle() + local f = function() + local items = {} + for path, path_type in vim.fs.dir(cwd, { depth = math.huge }) do + if not poke_picker() then return end + if path_type == 'file' and H.is_file_text(string.format('%s/%s', cwd, path)) then table.insert(items, path) end + end + MiniPick.set_picker_items(items) + end + + vim.schedule(coroutine.wrap(f)) +end + +H.grep_get_tool = function() + if H.is_executable('rg') then return 'rg' end + if H.is_executable('git') then return 'git' end + return 'fallback' +end + +--stylua: ignore +H.grep_get_command = function(tool, pattern) + if tool == 'rg' then + return { + 'rg', '--column', '--line-number', '--no-heading', '--hidden', '--no-follow', '--color=never', '--smart-case', + '--', pattern, + } + end + if tool == 'git' then + local res = { 'git', 'grep', '--column', '--line-number', '--color=never', '--', pattern } + if vim.o.ignorecase then table.insert(res, 6, '--ignore-case') end + return res + end + H.error([[Wrong 'tool' for `grep` builtin.]]) +end + +H.grep_fallback_items = function(pattern, cwd) + if vim.fn.has('nvim-0.9') == 0 then H.error('Tool "fallback" of `grep` builtin needs Neovim>=0.9.') end + cwd = cwd or '.' + local poke_picker = H.poke_picker_throttle() + local f = function() + local files, files_full = {}, {} + for path, path_type in vim.fs.dir(cwd, { depth = math.huge }) do + if not poke_picker() then return end + local path_full = string.format('%s/%s', cwd, path) + if path_type == 'file' and H.is_file_text(path_full) then + table.insert(files, path) + table.insert(files_full, path_full) + end + end + + local items = {} + for i, path in ipairs(files_full) do + local file = files[i] + if not poke_picker() then return end + for lnum, l in ipairs(vim.fn.readfile(path)) do + local col = string.find(l, pattern) + if col ~= nil then table.insert(items, string.format('%s:%d:%d:%s', file, lnum, col, l)) end + end + end + + MiniPick.set_picker_items(items) + end + + vim.schedule(coroutine.wrap(f)) +end + +-- Async ---------------------------------------------------------------------- +H.schedule_resume_is_active = vim.schedule_wrap(function(co) coroutine.resume(co, MiniPick.is_picker_active()) end) + +H.poke_picker_throttle = function(querytick_ref) + -- Allow calling this even if no picker is active + if not MiniPick.is_picker_active() then return function() return true end end + + local latest_time, dont_check_querytick = vim.loop.hrtime(), querytick_ref == nil + local threshold = 1000000 * H.get_config().delay.async + local hrtime = vim.loop.hrtime + local poke_is_picker_active = MiniPick.poke_is_picker_active + return function() + local now = hrtime() + if (now - latest_time) < threshold then return true end + latest_time = now + -- Return positive if picker is active and no query updates (if asked) + return poke_is_picker_active() and (dont_check_querytick or querytick_ref == H.querytick) + end +end + +-- Utilities ------------------------------------------------------------------ +H.error = function(msg) error(string.format('(mini.pick) %s', msg), 0) end + +H.is_valid_buf = function(buf_id) return type(buf_id) == 'number' and vim.api.nvim_buf_is_valid(buf_id) end + +H.is_valid_win = function(win_id) return type(win_id) == 'number' and vim.api.nvim_win_is_valid(win_id) end + +H.is_array_of = function(x, ref_type) + if not vim.tbl_islist(x) then return false end + for i = 1, #x do + if type(x[i]) ~= ref_type then return false end + end + return true +end + +H.create_scratch_buf = function() + local buf_id = vim.api.nvim_create_buf(false, true) + vim.bo[buf_id].matchpairs = '' + vim.b[buf_id].minicursorword_disable = true + vim.b[buf_id].miniindentscope_disable = true + return buf_id +end + +H.get_first_valid_normal_window = function() + for _, win_id in ipairs(vim.api.nvim_tabpage_list_wins(0)) do + if vim.api.nvim_win_get_config(win_id).relative == '' then return win_id end + end +end + +H.set_buflines = function(buf_id, lines) pcall(vim.api.nvim_buf_set_lines, buf_id, 0, -1, false, lines) end + +H.set_winbuf = function(win_id, buf_id) vim.api.nvim_win_set_buf(win_id, buf_id) end + +H.set_extmark = function(...) pcall(vim.api.nvim_buf_set_extmark, ...) end + +H.set_cursor = function(win_id, lnum, col) pcall(vim.api.nvim_win_set_cursor, win_id, { lnum or 1, (col or 1) - 1 }) end + +H.set_curwin = function(win_id) + if not H.is_valid_win(win_id) then return end + -- Explicitly preserve cursor to fix Neovim<=0.9 after choosing position in + -- already shown buffer + local cursor = vim.api.nvim_win_get_cursor(win_id) + vim.api.nvim_set_current_win(win_id) + H.set_cursor(win_id, cursor[1], cursor[2] + 1) +end + +H.clear_namespace = function(buf_id, ns_id) pcall(vim.api.nvim_buf_clear_namespace, buf_id, ns_id, 0, -1) end + +H.replace_termcodes = function(x) + if x == nil then return nil end + return vim.api.nvim_replace_termcodes(x, true, true, true) +end + +H.expand_callable = function(x) return vim.is_callable(x) and x() or x end + +H.expandcmd = function(x) + local ok, res = pcall(vim.fn.expandcmd, x) + return ok and res or x +end + +H.redraw = function() vim.cmd('redraw') end + +H.redraw_scheduled = vim.schedule_wrap(H.redraw) + +H.getcharstr = function(delay_async) + -- Ensure that redraws still happen + H.timers.getcharstr:start(0, delay_async, H.redraw_scheduled) + H.cache.is_in_getcharstr = true + local ok, char = pcall(vim.fn.getcharstr) + H.cache.is_in_getcharstr = nil + H.timers.getcharstr:stop() + + -- Terminate if no input, on hard-coded , or outside mouse click + local main_win_id + if H.pickers.active ~= nil then main_win_id = H.pickers.active.windows.main end + local is_bad_mouse_click = vim.v.mouse_winid ~= 0 and vim.v.mouse_winid ~= main_win_id + if not ok or char == '' or char == '\3' or is_bad_mouse_click then return end + return char +end + +H.tolower = (function() + -- Cache `tolower` for speed + local tolower = vim.fn.tolower + return function(x) + -- `vim.fn.tolower` can throw errors on bad string (like with '\0') + local ok, res = pcall(tolower, x) + return ok and res or string.lower(x) + end +end)() + +H.win_update_hl = function(win_id, new_from, new_to) + if not H.is_valid_win(win_id) then return end + + local new_entry = new_from .. ':' .. new_to + local replace_pattern = string.format('(%s:[^,]*)', vim.pesc(new_from)) + local new_winhighlight, n_replace = vim.wo[win_id].winhighlight:gsub(replace_pattern, new_entry) + if n_replace == 0 then new_winhighlight = new_winhighlight .. ',' .. new_entry end + + -- Use `pcall()` because Neovim<0.8 doesn't allow non-existing highlight + -- groups inside `winhighlight` (like `FloatTitle` at the time). + pcall(function() vim.wo[win_id].winhighlight = new_winhighlight end) +end + +H.win_trim_to_width = function(win_id, text) + local win_width = vim.api.nvim_win_get_width(win_id) + return vim.fn.strcharpart(text, vim.fn.strchars(text) - win_width, win_width) +end + +H.win_get_bottom_border = function(win_id) + local border = vim.api.nvim_win_get_config(win_id).border or {} + return border[6] or ' ' +end + +H.seq_along = function(arr) + if arr == nil then return nil end + local res = {} + for i = 1, #arr do + table.insert(res, i) + end + return res +end + +H.get_next_char_bytecol = function(line_str, col) + if type(line_str) ~= 'string' then return col end + local utf_index = vim.str_utfindex(line_str, math.min(line_str:len(), col)) + return vim.str_byteindex(line_str, utf_index) +end + +H.is_file_text = function(path) + local fd = vim.loop.fs_open(path, 'r', 1) + local is_text = vim.loop.fs_read(fd, 1024):find('\0') == nil + vim.loop.fs_close(fd) + return is_text +end + +H.full_path = function(path) return (vim.fn.fnamemodify(path, ':p'):gsub('/$', '')) end + +return MiniPick diff --git a/readmes/mini-pick.md b/readmes/mini-pick.md new file mode 100644 index 00000000..c5abd07d --- /dev/null +++ b/readmes/mini-pick.md @@ -0,0 +1,332 @@ + + + +[![GitHub license](https://badgen.net/github/license/echasnovski/mini.nvim)](https://github.com/echasnovski/mini.nvim/blob/main/LICENSE) + + +### Pick anything + +For full experience needs [nvim-tree/nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) plugin and [BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) (but works without it). + +See more details in [Features](#features) and [help file](../doc/mini-pick.txt). + +--- + +⦿ This is a part of [mini.nvim](https://github.com/echasnovski/mini.nvim) library. Please use [this link](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-pick.md) if you want to mention this module. + +⦿ All contributions (issues, pull requests, discussions, etc.) are done inside of 'mini.nvim'. + +⦿ See the repository page to learn about common design principles and configuration recipes. + +--- + +If you want to help this project grow but don't know where to start, check out [contributing guides of 'mini.nvim'](https://github.com/echasnovski/mini.nvim/blob/main/CONTRIBUTING.md) or leave a Github star for 'mini.nvim' project and/or any its standalone Git repositories. + +## Demo + +https://github.com/echasnovski/mini.nvim/assets/24854248/f2095861-d0a1-4df8-bf7a-7218d4262dec + +## Features + +- Single window general purpose interface for picking element from any array. + +- On demand toggleable preview and info views. + +- Interactive query matching (filter+sort) with fast non-blocking default which does fuzzy matching and allows other modes. + +- Built-in pickers: + - Files. + - Pattern match (for fixed pattern and with live feedback). + - Buffers. + - Help tags. + - CLI output. + - Resume latest picker. + +- `:Pick` command to work with extensible `MiniPick.registry`. + +- `vim.ui.select()` wrapper. + +- Rich and customizable built-in actions when picker is active: + - Manually change currently focused item. + - Scroll vertically and horizontally. + - Toggle preview or info view. + - Mark/unmark items to choose later. + - Refine current matches (make them part of a new picker). + - And many more. + +- Minimal yet flexible source specification with: + - Items (array, callable, or manually set later). + - Source name. + - Working directory. + - Matching algorithm. + - Way matches are shown in main window. + - Item preview. + - "On choice" action for current and marked items. + +- Custom actions/keys can be configured globally, per buffer, or per picker. + +- Out of the box support for 'ignorecase' and 'smartcase'. + +- Match caching to increase responsiveness on repeated prompts. + +Notes: +- Works on all supported versions but using Neovim>=0.9 is recommended. Neovim>=0.10 will give more visual feedback in floating window footer. + +Read more information, see these tags in help file: +- `*MiniPick-overview*` +- `*MiniPick-source*` +- `*MiniPick-actions*` +- `*MiniPick-examples*` +- `*MiniPick.builtin*` + +## Overview + +General idea is to take array of objects, display them with interactive filter/sort/navigate/preview, and allow to choose one or more items. + +### How to start a picker + +- Use `MiniPick.start()` with `opts.source` defining source.
+ Example: `MiniPick.start({ source = { items = vim.fn.readdir('.') } })` + +- Use any of `MiniPick.builtin` pickers directly.
+ Example: `MiniPick.builtin.files({ tool = 'git' })` + +- Use `:Pick` command which uses customizable pickers from `MiniPick.registry`.
+ Example: `:Pick files tool=git` + +### User interface + +UI consists from a single window capable of displaying three different views: +- "Main" - where current query matches are shown. +- "Preview" - preview of current item (toggle with ``). +- "Info" - general info about picker and its state (toggle with ``). + +Current prompt is displayed (in Neovim>=0.9) at the top left of the window border with vertical line indicating caret (current input position). + +Bottom part of window border displays (in Neovim>=0.10) extra visual feedback: +- Left part is a picker name. +- Right part contains information in the format
+ ` | | / ` + +When picker is busy (like if there are no items yet set or matching is active) window border changes color to be `MiniPickBorderBusy` after `config.delay.busy` milliseconds of idle time. + +### Life cycle + +- Type characters to filter and sort matches. It uses `MiniPick.default_match()` with `query` being an array of pressed characters.
+ Overview of how it matches: + - If query starts with `'`, the match is exact. + - If query starts with `^`, the match is exact at start. + - If query starts with `$`, the match is exact at end. + - If query starts with `*`, the match is forced to be fuzzy. + - Otherwise match is fuzzy. + - Sorting is done to first minimize match width and then match start. + Nothing more: no favoring certain places in string, etc. + +- Type special keys to perform actions. Here are some basic ones: + - `` / `` moves down; `` / `` moves up. + - `` / `` moves prompt caret left / right. + - `` toggles information window with all available mappings. + - `` toggles preview. + - `` / `` toggles current / all item(s) as (un)marked. + - `` / `` makes all matches or marked items as new picker. + - `` / `` chooses current/marked item(s). + - `` / `` stops picker. + +## Installation + +This plugin can be installed as part of 'mini.nvim' library (**recommended**) or as a standalone Git repository. + + + + + +During beta-testing phase there is only one branch to install from: + +- `main` (default, **recommended**) will have latest development version of plugin. All changes since last stable release should be perceived as being in beta testing phase (meaning they already passed alpha-testing and are moderately settled). + + +Here are code snippets for some common installation methods (use only one): + +
+With folke/lazy.nvim + + + + + + + + + + + + + + + + + + + + + + + + + +
Github repoBranch Code snippet
'mini.nvim' libraryMain { 'echasnovski/mini.nvim', version = false },
Standalone pluginMain { 'echasnovski/mini.pick', version = false },
+
+ +
+With wbthomason/packer.nvim + + + + + + + + + + + + + + + + + + + + + + + + +
Github repoBranch Code snippet
'mini.nvim' libraryMain use 'echasnovski/mini.nvim'
Standalone plugin Main use 'echasnovski/mini.pick'
+
+ +
+With junegunn/vim-plug + + + + + + + + + + + + + + + + + + + + + + + + +
Github repoBranch Code snippet
'mini.nvim' libraryMain Plug 'echasnovski/mini.nvim'
Standalone plugin Main Plug 'echasnovski/mini.pick'
+
+ +
+ +**Important**: don't forget to call `require('mini.pick').setup()` to enable its functionality. + +**Note**: if you are on Windows, there might be problems with too long file paths (like `error: unable to create file : Filename too long`). Try doing one of the following: +- Enable corresponding git global config value: `git config --system core.longpaths true`. Then try to reinstall. + +## Default config + +```lua +-- No need to copy this inside `setup()`. Will be used automatically. +{ + -- Delays (in ms; should be at least 1) + delay = { + -- Delay between forcing asynchronous behavior + async = 10, + + -- Delay between computation start and visual feedback about it + busy = 50, + }, + + -- Keys for performing actions. See `:h MiniPick-actions`. + mappings = { + caret_left = '', + caret_right = '', + + choose = '', + choose_in_split = '', + choose_in_tabpage = '', + choose_in_vsplit = '', + choose_marked = '', + + delete_char = '', + delete_char_right = '', + delete_left = '', + delete_word = '', + + mark = '', + mark_all = '', + + move_down = '', + move_start = '', + move_up = '', + + paste = '', + + refine = '', + refine_marked = '', + + scroll_down = '', + scroll_left = '', + scroll_right = '', + scroll_up = '', + + stop = '', + + toggle_info = '', + toggle_preview = '', + }, + + -- General options + options = { + -- Whether to show content from bottom to top + content_from_bottom = false, + + -- Whether to cache matches (more speed and memory on repeated prompts) + use_cache = false, + }, + + -- Source definition. See `:h MiniPick-source`. + source = { + items = nil, + name = nil, + cwd = nil, + + match = nil, + show = nil, + preview = nil, + + choose = nil, + choose_marked = nil, + }, + + -- Window related options + window = { + -- Float window config (table or callable returning it) + config = nil, + }, +} +``` + +## Similar plugins + +- [nvim-telescope/telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) +- [ibhagwan/fzf-lua](https://github.com/ibhagwan/fzf-lua) diff --git a/scripts/basic-setup_init.lua b/scripts/basic-setup_init.lua index d5c2d8a3..8697cbf8 100644 --- a/scripts/basic-setup_init.lua +++ b/scripts/basic-setup_init.lua @@ -38,6 +38,7 @@ local test_actions = { ['move'] = function() require('mini.move').setup() end, ['operators'] = function() require('mini.operators').setup() end, ['pairs'] = function() require('mini.pairs').setup() end, + ['pick'] = function() require('mini.pick').setup() end, ['sessions'] = function() require('mini.sessions').setup({ directory = '' }) end, ['splitjoin'] = function() require('mini.splitjoin').setup() end, ['starter'] = function() require('mini.starter').setup() end, diff --git a/scripts/dual_sync.sh b/scripts/dual_sync.sh index fe3c0f2e..c0db1cde 100755 --- a/scripts/dual_sync.sh +++ b/scripts/dual_sync.sh @@ -82,6 +82,7 @@ sync_module "misc" sync_module "move" sync_module "operators" sync_module "pairs" +sync_module "pick" sync_module "sessions" sync_module "splitjoin" sync_module "starter" diff --git a/scripts/minidoc.lua b/scripts/minidoc.lua index 0f0b7e71..3c8a01f8 100644 --- a/scripts/minidoc.lua +++ b/scripts/minidoc.lua @@ -28,6 +28,7 @@ local modules = { 'move', 'operators', 'pairs', + 'pick', 'sessions', 'splitjoin', 'starter', diff --git a/tests/dir-pick/builtin-tests/dir1/file1-1 b/tests/dir-pick/builtin-tests/dir1/file1-1 new file mode 100644 index 00000000..1a2e58ae --- /dev/null +++ b/tests/dir-pick/builtin-tests/dir1/file1-1 @@ -0,0 +1,5 @@ +dir1/file1-1 + +aaa +bbb +ccc diff --git a/tests/dir-pick/builtin-tests/dir1/file1-2 b/tests/dir-pick/builtin-tests/dir1/file1-2 new file mode 100644 index 00000000..33ab8b74 --- /dev/null +++ b/tests/dir-pick/builtin-tests/dir1/file1-2 @@ -0,0 +1,5 @@ +dir1/file1-2 + +aaa +bbb +ccc diff --git a/tests/dir-pick/builtin-tests/dir2/file2-1 b/tests/dir-pick/builtin-tests/dir2/file2-1 new file mode 100644 index 00000000..e4959600 --- /dev/null +++ b/tests/dir-pick/builtin-tests/dir2/file2-1 @@ -0,0 +1,5 @@ +dir2/file2-1 + +aaa +bbb +ccc diff --git a/tests/dir-pick/builtin-tests/file b/tests/dir-pick/builtin-tests/file new file mode 100644 index 00000000..1611a526 --- /dev/null +++ b/tests/dir-pick/builtin-tests/file @@ -0,0 +1,5 @@ +file + +aaa +bbb +ccc diff --git a/tests/dir-pick/file b/tests/dir-pick/file new file mode 100644 index 00000000..e69de29b diff --git a/tests/dir-pick/lua/nvim-web-devicons.lua b/tests/dir-pick/lua/nvim-web-devicons.lua new file mode 100644 index 00000000..eeb1bb70 --- /dev/null +++ b/tests/dir-pick/lua/nvim-web-devicons.lua @@ -0,0 +1,17 @@ +vim.cmd('hi DevIconLicense guifg=#111111') +vim.cmd('hi DevIconMakefile guifg=#222222') +vim.cmd('hi DevIconGif guifg=#333333') +vim.cmd('hi DevIconLua guifg=#444444') +vim.cmd('hi DevIconTxt guifg=#555555') +vim.cmd('hi DevIconDefault guifg=#666666') + +return { + get_icon = function(filename, _, options) + if filename == 'LICENSE' then return '', 'DevIconLicense' end + if filename == 'Makefile' then return '', 'DevIconMakefile' end + if vim.endswith(filename, 'gif') then return '', 'DevIconGif' end + if vim.endswith(filename, 'lua') then return '', 'DevIconLua' end + if vim.endswith(filename, 'txt') then return '', 'DevIconTxt' end + if (options or {}).default then return '', 'DevIconDefault' end + end, +} diff --git a/tests/dir-pick/mocks/spawn.lua b/tests/dir-pick/mocks/spawn.lua new file mode 100644 index 00000000..6086b166 --- /dev/null +++ b/tests/dir-pick/mocks/spawn.lua @@ -0,0 +1,50 @@ +_G.process_log = {} + +local n_pid, n_stdout = 0, 0 +local new_process = function(pid) + return { + pid = pid, + close = function(_) table.insert(_G.process_log, 'Process ' .. pid .. ' was closed.') end, + } +end + +-- Mock `stdout` by using global `_G.stdout_data_feed` array as source. +-- Each feed's element should be either string (for usable data) or a table +-- with `err` field (for error). +vim.loop.new_pipe = function() + n_stdout = n_stdout + 1 + local cur_stdout_id = 'Stdout_' .. n_stdout + + return { + read_start = function(_, callback) + -- It is not possible in Neovim<=0.9 to execute `vim.fn` functions during + -- `pipe:read_start()` + local vim_fn_orig = vim.deepcopy(vim.fn) + vim.fn = setmetatable({}, { __index = function() error('Can not use `vim.fn` during `read_start`.') end }) + + for _, x in ipairs(_G.stdout_data_feed or {}) do + if type(x) == 'table' then callback(x.err, nil) end + if type(x) == 'string' then callback(nil, x) end + end + callback(nil, nil) + + vim.fn = vim_fn_orig + end, + close = function() table.insert(_G.process_log, 'Stdout ' .. cur_stdout_id .. ' was closed.') end, + } +end + +_G.spawn_log = {} +vim.loop.spawn = function(path, options, on_exit) + local options_without_callables = vim.deepcopy(options) + options_without_callables.stdio = nil + table.insert(_G.spawn_log, { executable = path, options = options_without_callables }) + + vim.schedule(function() on_exit() end) + + n_pid = n_pid + 1 + local pid = 'Pid_' .. n_pid + return new_process(pid), pid +end + +vim.loop.process_kill = function(process) table.insert(_G.process_log, 'Process ' .. process.pid .. ' was killed.') end diff --git a/tests/dir-pick/real-files/LICENSE b/tests/dir-pick/real-files/LICENSE new file mode 100644 index 00000000..ac3dbebb --- /dev/null +++ b/tests/dir-pick/real-files/LICENSE @@ -0,0 +1 @@ +MIT (c) diff --git a/tests/dir-pick/real-files/Makefile b/tests/dir-pick/real-files/Makefile new file mode 100644 index 00000000..eeecfe5c --- /dev/null +++ b/tests/dir-pick/real-files/Makefile @@ -0,0 +1,3 @@ +VAR ?= 1 + +all: test diff --git a/tests/dir-pick/real-files/a.lua b/tests/dir-pick/real-files/a.lua new file mode 100644 index 00000000..140a9a09 --- /dev/null +++ b/tests/dir-pick/real-files/a.lua @@ -0,0 +1,5 @@ +local a = 1 +local t = { + x = math.max(1, 2), + y = math.min(1, 2), +} diff --git a/tests/dir-pick/real-files/b.txt b/tests/dir-pick/real-files/b.txt new file mode 100644 index 00000000..ae951ea8 --- /dev/null +++ b/tests/dir-pick/real-files/b.txt @@ -0,0 +1,26 @@ +Line 1 +Line 2 +Line 3 +Line 4 +Line 5 +Line 6 +Line 7 +Line 8 +Line 9 +Line 10 +Line 11 +Line 12 +Line 13 +Line 14 +Line 15 +Line 16 +Line 17 +Line 18 +Line 19 +Line 20 +Line 21 +Line 22 +Line 23 +Line 24 +Line 25 +Line 26 diff --git a/tests/dir-pick/real-files/c.gif b/tests/dir-pick/real-files/c.gif new file mode 100644 index 0000000000000000000000000000000000000000..ccdd7b74ab3f0af561a2a03b309262ce404b8699 GIT binary patch literal 137 zcmZ?wbhEHbv}fRCSjfa6sOI?SWj_NLDEI?DCEQhgu)I*|#KP<4YvZDI6Mrae$vvmbc6wE0 l^i;PU3-qoA-|1Pz=Ih?_ukVnri0hJ!?RVBq4`N`j1^^EyFmeC@ literal 0 HcmV?d00001 diff --git a/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete new file mode 100644 index 00000000..1c58b660 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|~ buffers +04|~ cli +05|~ files +06|~ grep +07|~ grep_live +08|~ help +09|~ resume +10|:Pick buffers + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|11111222222222222222 +04|11111333333333333333 +05|11111333333333333333 +06|11111333333333333333 +07|11111333333333333333 +08|11111333333333333333 +09|11111333333333333333 +10|44444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-002 b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-002 new file mode 100644 index 00000000..63e4f3cc --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ buffers +09|~ files +10|:Pick buffers + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|11111111111111111111 +04|11111111111111111111 +05|11111111111111111111 +06|11111111111111111111 +07|11111111111111111111 +08|11111222222222222222 +09|11111333333333333333 +10|44444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-003 b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-003 new file mode 100644 index 00000000..7b7a7c1d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua----Pick---has-proper-complete-003 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ buffers +09|~ files +10|:Pick buffers x + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|11111111111111111111 +04|11111111111111111111 +05|11111111111111111111 +06|11111111111111111111 +07|11111111111111111111 +08|11111222222222222222 +09|11111333333333333333 +10|44444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua----Pick---works b/tests/screenshots/tests-test_pick.lua----Pick---works new file mode 100644 index 00000000..e04461aa --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua----Pick---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ tests/dir-pick/real-f…│ +07|│ [No Name] │ +08|│ tests/dir-pick/real-f…│ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444445211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666665211111111111111 +09|2777777777777777777777777211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua----Pick---works-002 b/tests/screenshots/tests-test_pick.lua----Pick---works-002 new file mode 100644 index 00000000..85c84fca --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua----Pick---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ tests/dir-pick/real-f…│ +07|│ [No Name] │ +08|│ [Scratch] │ +09|│ tests/dir-pick/real-f…│ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444445211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666665211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts new file mode 100644 index 00000000..a7d8c1a6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> abcd▏──┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233333332221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|255555555521111 +09|222222222221111 +10|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-002 b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-002 new file mode 100644 index 00000000..84b9ebc4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-002 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ab▏cd──┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233333332221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|255555555521111 +09|222222222221111 +10|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-003 b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-003 new file mode 100644 index 00000000..55ae57f5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---moves-by-query-parts-003 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏abcd──┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233333332221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|255555555521111 +09|222222222221111 +10|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---works b/tests/screenshots/tests-test_pick.lua---Caret---works new file mode 100644 index 00000000..bb36302a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---works @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ac▏b───┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233333322221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|255555555521111 +09|222222222221111 +10|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---works-002 b/tests/screenshots/tests-test_pick.lua---Caret---works-002 new file mode 100644 index 00000000..8c059368 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---works-002 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> a▏b────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233333222221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|255555555521111 +09|222222222221111 +10|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Caret---works-003 b/tests/screenshots/tests-test_pick.lua---Caret---works-003 new file mode 100644 index 00000000..b452a859 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Caret---works-003 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> a▏─────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233332222221111 +04|245555555521111 +05|266666666621111 +06|266666666621111 +07|266666666621111 +08|266666666621111 +09|222222222221111 +10|777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations new file mode 100644 index 00000000..4e4d6361 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|[No Name] +09| +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|2222222222222222222222222222222222222222 +09|0000000000000000000000000000000000000000 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|3333333333333333333333333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-002 b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-002 new file mode 100644 index 00000000..636b0037 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| │ +02|~ │~ +03|~ │~ +04|~ │~ +05|~ │~ +06|~ │~ +07|~ │~ +08|[No Name] [No Name] +09| +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000010000000000000000000 +02|2222222222222222222212222222222222222222 +03|2222222222222222222212222222222222222222 +04|2222222222222222222212222222222222222222 +05|2222222222222222222212222222222222222222 +06|2222222222222222222212222222222222222222 +07|2222222222222222222212222222222222222222 +08|3333333333333333333334444444444444444444 +09|0000000000000000000000000000000000000000 +10|2222222222222222222222222222222222222222 +11|2222222222222222222222222222222222222222 +12|2222222222222222222222222222222222222222 +13|2222222222222222222222222222222222222222 +14|2222222222222222222222222222222222222222 +15|1111111111111111111111111111111111111111 diff --git a/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-003 b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-003 new file mode 100644 index 00000000..bdf1d5d0 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Choose---works-for-split-tab-variations-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| 3 [No Name] [No Name] X +02| +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0100000000000222222222223333333333333330 +02|4444444444444444444444444444444444444444 +03|5555555555555555555555555555555555555555 +04|5555555555555555555555555555555555555555 +05|5555555555555555555555555555555555555555 +06|5555555555555555555555555555555555555555 +07|5555555555555555555555555555555555555555 +08|5555555555555555555555555555555555555555 +09|5555555555555555555555555555555555555555 +10|5555555555555555555555555555555555555555 +11|5555555555555555555555555555555555555555 +12|5555555555555555555555555555555555555555 +13|5555555555555555555555555555555555555555 +14|5555555555555555555555555555555555555555 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item new file mode 100644 index 00000000..b52cc66b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│General │ +07|│Source name │ My name │ +08|│Source cwd │ mock/cur│ +09|│Total items │ 3 │ +10|│Matched items │ 3 │ +11|│Marked items │ 0 │ +12|│Current index │ 1 │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2444444455555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-002 b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-002 new file mode 100644 index 00000000..c5c5dc98 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│General │ +07|│Source name │ My name │ +08|│Source cwd │ mock/cur│ +09|│Total items │ 3 │ +10|│Matched items │ 3 │ +11|│Marked items │ 0 │ +12|│Current index │ 2 │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2444444455555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-003 b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-003 new file mode 100644 index 00000000..cd97a548 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│General │ +07|│Source name │ My name │ +08|│Source cwd │ mock/cur│ +09|│Total items │ 3 │ +10|│Matched items │ 3 │ +11|│Marked items │ 1 │ +12|│Current index │ 2 │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2444444455555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-004 b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-004 new file mode 100644 index 00000000..c5c5dc98 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---is-updated-after-moving-marking-current-item-004 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│General │ +07|│Source name │ My name │ +08|│Source cwd │ mock/cur│ +09|│Total items │ 3 │ +10|│Matched items │ 3 │ +11|│Marked items │ 0 │ +12|│Current index │ 2 │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2444444455555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---respects-custom-mappings b/tests/screenshots/tests-test_pick.lua---Info-view---respects-custom-mappings new file mode 100644 index 00000000..cb1dd004 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---respects-custom-mappings @@ -0,0 +1,43 @@ +--|---------|---------|---------|---------|---------|---------| +01|┌Info─────────────────────────────────┐ +02|│General │ +03|│Source name │ My name │ +04|│Source cwd │ mock/current-dir │ +05|│Total items │ 3 │ +06|│Matched items │ 3 │ +07|│Marked items │ 0 │ +08|│Current index │ 1 │ +09|│ │ +10|│Mappings (custom) │ +11|│Another action │ │ +12|│Custom action │ │ +13|│ │ +14|│Mappings (built-in) │ +15|│Caret left │ │ +16|│Caret right │ │ +17|│Choose │ a │ +18|│Choose in split │ │ +19|└─────────────────────────────────────┘ +20| + +--|---------|---------|---------|---------|---------|---------| +01|011110000000000000000000000000000000000222222222222222222222 +02|033333334444444444444444444444444444440555555555555555555555 +03|044444444444444444444444444444444444440555555555555555555555 +04|044444444444444444444444444444444444440555555555555555555555 +05|044444444444444444444444444444444444440555555555555555555555 +06|044444444444444444444444444444444444440555555555555555555555 +07|044444444444444444444444444444444444440555555555555555555555 +08|044444444444444444444444444444444444440555555555555555555555 +09|044444444444444444444444444444444444440555555555555555555555 +10|033333333333333333444444444444444444440555555555555555555555 +11|044444444444444444444444444444444444440555555555555555555555 +12|044444444444444444444444444444444444440555555555555555555555 +13|044444444444444444444444444444444444440555555555555555555555 +14|033333333333333333334444444444444444440555555555555555555555 +15|044444444444444444444444444444444444440555555555555555555555 +16|044444444444444444444444444444444444440555555555555555555555 +17|044444444444444444444444444444444444440555555555555555555555 +18|044444444444444444444444444444444444440555555555555555555555 +19|000000000000000000000000000000000000000555555555555555555555 +20|666666666666666666666666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll b/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll new file mode 100644 index 00000000..f59f9e63 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│l │ +07|│ name │ │ +08|│ cwd │ mock/current-d│ +09|│items │ 1 │ +10|│d items │ 1 │ +11|│ items │ 0 │ +12|│t index │ 1 │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-002 b/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-002 new file mode 100644 index 00000000..e64a46cb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Info-view---supports-vertical-and-horizontal-scroll-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Info────────────────────┐ +06|│General │ +07|│Source name │ │ +12|│Choose in split │ │ +12|│Caret right │ │ +13|│Choose │ │ +14|│Choose in split │ │ +15|│Choose in tabpage │ │ +16|│Choose in vsplit │ │ +17|│Choose marked │ │ +18|│Delete char │ │ +19|│Delete char right │ │ +20|│Delete left │ │ +21|│Delete word │ │ +22|│Mark │ │ +23|│Mark all │ │ +24|│Move down │ │ +25|│Move start │ │ +26|│Move up │ │ +27|│Paste │ │ +28|│Refine │ │ +29|│Refine marked │ │ +30|│Scroll down │ │ +31|│Scroll left │ │ +32|│Scroll right │ │ +33|│Scroll up │ │ +34|│Stop │ │ +35|│Toggle info │ │ +36|│Toggle preview │ │ +37|│ │ +38|│ │ +39|└─────────────────────────────────────┘ +40| + +--|---------|---------|---------|---------|---------|---------| +01|011110000000000000000000000000000000000222222222222222222222 +02|033333334444444444444444444444444444440555555555555555555555 +03|044444444444444444444444444444444444440555555555555555555555 +04|044444444444444444444444444444444444440555555555555555555555 +05|044444444444444444444444444444444444440555555555555555555555 +06|044444444444444444444444444444444444440555555555555555555555 +07|044444444444444444444444444444444444440555555555555555555555 +08|044444444444444444444444444444444444440555555555555555555555 +09|044444444444444444444444444444444444440555555555555555555555 +10|033333333333333333334444444444444444440555555555555555555555 +11|044444444444444444444444444444444444440555555555555555555555 +12|044444444444444444444444444444444444440555555555555555555555 +13|044444444444444444444444444444444444440555555555555555555555 +14|044444444444444444444444444444444444440555555555555555555555 +15|044444444444444444444444444444444444440555555555555555555555 +16|044444444444444444444444444444444444440555555555555555555555 +17|044444444444444444444444444444444444440555555555555555555555 +18|044444444444444444444444444444444444440555555555555555555555 +19|044444444444444444444444444444444444440555555555555555555555 +20|044444444444444444444444444444444444440555555555555555555555 +21|044444444444444444444444444444444444440555555555555555555555 +22|044444444444444444444444444444444444440555555555555555555555 +23|044444444444444444444444444444444444440555555555555555555555 +24|044444444444444444444444444444444444440555555555555555555555 +25|044444444444444444444444444444444444440555555555555555555555 +26|044444444444444444444444444444444444440555555555555555555555 +27|044444444444444444444444444444444444440555555555555555555555 +28|044444444444444444444444444444444444440555555555555555555555 +29|044444444444444444444444444444444444440555555555555555555555 +30|044444444444444444444444444444444444440555555555555555555555 +31|044444444444444444444444444444444444440555555555555555555555 +32|044444444444444444444444444444444444440555555555555555555555 +33|044444444444444444444444444444444444440555555555555555555555 +34|044444444444444444444444444444444444440555555555555555555555 +35|044444444444444444444444444444444444440555555555555555555555 +36|044444444444444444444444444444444444440555555555555555555555 +37|066666666666666666666666666666666666660555555555555555555555 +38|066666666666666666666666666666666666660555555555555555555555 +39|000000000000000000000000000000000000000555555555555555555555 +40|777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show new file mode 100644 index 00000000..97485019 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-002 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-002 new file mode 100644 index 00000000..1e3e9805 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-002 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-003 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-003 new file mode 100644 index 00000000..e1200e31 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-003 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|055555555504444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-004 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-004 new file mode 100644 index 00000000..f4beb0c2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-004 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-005 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-005 new file mode 100644 index 00000000..d886ff99 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-005 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-006 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-006 new file mode 100644 index 00000000..3b0c84d3 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-006 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|055555555504444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-007 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-007 new file mode 100644 index 00000000..317badd2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-007 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-008 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-008 new file mode 100644 index 00000000..c8e79759 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-008 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|055555555504444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-009 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-009 new file mode 100644 index 00000000..4ce2086f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-009 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-010 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-010 new file mode 100644 index 00000000..97485019 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-010 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-011 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-011 new file mode 100644 index 00000000..4ce2086f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-011 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-012 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-012 new file mode 100644 index 00000000..c8e79759 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-012 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|055555555504444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-013 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-013 new file mode 100644 index 00000000..f5c3221f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-013 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-014 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-014 new file mode 100644 index 00000000..0310d209 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-014 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-015 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-015 new file mode 100644 index 00000000..d886ff99 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-015 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-016 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-016 new file mode 100644 index 00000000..0f69a9ab --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-016 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-017 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-017 new file mode 100644 index 00000000..4785b7ea --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-017 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│2 │ +3|│3 │ +4|│4 │ +5|│5 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-018 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-018 new file mode 100644 index 00000000..d7fede03 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-018 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│2 │ +3|│3 │ +4|│4 │ +5|│5 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-019 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-019 new file mode 100644 index 00000000..97485019 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-019 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-020 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-020 new file mode 100644 index 00000000..d886ff99 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-020 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-021 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-021 new file mode 100644 index 00000000..4ce2086f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-021 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-022 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-022 new file mode 100644 index 00000000..97485019 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-022 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-023 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-023 new file mode 100644 index 00000000..4ce2086f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-023 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│6 │ +3|│7 │ +4|│8 │ +5|│9 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|033333333304444 +4|033333333304444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-024 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-024 new file mode 100644 index 00000000..d886ff99 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-024 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│4 │ +3|│5 │ +4|│6 │ +5|│7 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|033333333304444 +5|033333333304444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-025 b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-025 new file mode 100644 index 00000000..97485019 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---properly-computes-items-range-to-show-025 @@ -0,0 +1,17 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│1 │ +3|│2 │ +4|│3 │ +5|│4 │ +6|└─────────┘ +7| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|055555555504444 +5|055555555504444 +6|000000000004444 +7|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries b/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries new file mode 100644 index 00000000..8e02f952 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> ▏─────────┐ +04|│a │ +05|│ab │ +06|│b │ +07|│bb │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23332222222222111111 +04|24444444444442111111 +05|25566666666662111111 +06|26666666666662111111 +07|26666666666662111111 +08|27777777777772111111 +09|22222222222222111111 +10|88888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries-002 b/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries-002 new file mode 100644 index 00000000..de4f9aa3 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---shows-marked-items-across-queries-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> b▏────────┐ +04|│b │ +05|│bb │ +06|│ab │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333222222222111111 +04|24555555555552111111 +05|26777777777772111111 +06|28977777777772111111 +07|2::::::::::::2111111 +08|2::::::::::::2111111 +09|22222222222222111111 +10|;;;;;;;;;;;;;;;;;;;; diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll new file mode 100644 index 00000000..c6f3f737 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│t 1 │ +05|│ long it…│ +06|│t 3 │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555621111 +06|255555555521111 +07|277777777721111 +08|277777777721111 +09|222222222221111 +10|888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-002 b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-002 new file mode 100644 index 00000000..84375823 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-002 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│1 │ +05|│ong item…│ +06|│3 │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555621111 +06|255555555521111 +07|277777777721111 +08|277777777721111 +09|222222222221111 +10|888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-003 b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-003 new file mode 100644 index 00000000..84375823 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-003 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│1 │ +05|│ong item…│ +06|│3 │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555621111 +06|255555555521111 +07|277777777721111 +08|277777777721111 +09|222222222221111 +10|888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-004 b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-004 new file mode 100644 index 00000000..a5853756 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-004 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│1 │ +05|│ong item…│ +06|│3 │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555621111 +06|244444444421111 +07|277777777721111 +08|277777777721111 +09|222222222221111 +10|888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-005 b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-005 new file mode 100644 index 00000000..d56e9d36 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-005 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│ │ +05|│item 2 │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555521111 +06|244444444421111 +07|266666666621111 +08|266666666621111 +09|222222222221111 +10|777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-006 b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-006 new file mode 100644 index 00000000..abe093d3 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---supports-horizontal-scroll-006 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│ort 1 │ +05|│ry long …│ +06|│ort 3 │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|244444444521111 +06|266666666621111 +07|277777777721111 +08|277777777721111 +09|222222222221111 +10|888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true new file mode 100644 index 00000000..91a4222d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> ▏───────────────┐ +04|│x2 │ +05|│x1 │ +06|│bb │ +07|│b │ +08|│a │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233322222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|244444444444444444421111111111 +08|255555555555555555521111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-002 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-002 new file mode 100644 index 00000000..d924221d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-002 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> ▏───────────────┐ +04|│x2 │ +05|│x1 │ +06|│bb │ +07|│b │ +08|│a │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233322222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|255555555555555555521111111111 +08|244444444444444444421111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-003 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-003 new file mode 100644 index 00000000..3674f45c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-003 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│bb │ +08|│b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|254444444444444444421111111111 +08|267777777777777777721111111111 +09|222222222222222222221111111111 +10|888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-004 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-004 new file mode 100644 index 00000000..e565fc69 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-004 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│bb │ +08|│b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|256666666666666666621111111111 +08|274444444444444444421111111111 +09|222222222222222222221111111111 +10|888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-005 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-005 new file mode 100644 index 00000000..3674f45c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-005 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│bb │ +08|│b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|254444444444444444421111111111 +08|267777777777777777721111111111 +09|222222222222222222221111111111 +10|888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-006 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-006 new file mode 100644 index 00000000..70257cfa --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-006 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> ▏───────────────┐ +04|│Item x2 │ +05|│Item x1 │ +06|│Item bb │ +07|│Item b │ +08|│Item a │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233322222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|244444444444444444421111111111 +08|255555555555555555521111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-007 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-007 new file mode 100644 index 00000000..0af404b7 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-007 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> ▏───────────────┐ +04|│Item x2 │ +05|│Item x1 │ +06|│Item bb │ +07|│Item b │ +08|│Item a │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233322222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|255555555555555555521111111111 +08|244444444444444444421111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-008 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-008 new file mode 100644 index 00000000..4d858796 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-008 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│Item bb │ +08|│Item b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|244444444444444444421111111111 +08|255555555555555555521111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-009 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-009 new file mode 100644 index 00000000..d73219a4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-009 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│Item bb │ +08|│Item b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|255555555555555555521111111111 +08|244444444444444444421111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-010 b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-010 new file mode 100644 index 00000000..4d858796 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Main-view---works-with-`content_from_bottom`=true-010 @@ -0,0 +1,23 @@ +--|---------|---------|---------| +01| +02|~ +03|┌> b▏──────────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│Item bb │ +08|│Item b │ +09|└──────────────────┘ +10| + +--|---------|---------|---------| +01|000000000000000000000000000000 +02|111111111111111111111111111111 +03|233332222222222222221111111111 +04|244444444444444444421111111111 +05|244444444444444444421111111111 +06|244444444444444444421111111111 +07|244444444444444444421111111111 +08|255555555555555555521111111111 +09|222222222222222222221111111111 +10|666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Mark---works-without-items-set b/tests/screenshots/tests-test_pick.lua---Mark---works-without-items-set new file mode 100644 index 00000000..626eaca1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Mark---works-without-items-set @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Move---works-when-no-items-are-set b/tests/screenshots/tests-test_pick.lua---Move---works-when-no-items-are-set new file mode 100644 index 00000000..626eaca1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Move---works-when-no-items-are-set @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---allows-'none'-as-border b/tests/screenshots/tests-test_pick.lua---Overall-view---allows-'none'-as-border new file mode 100644 index 00000000..e89f1d8a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---allows-'none'-as-border @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05| > ▏ +06|a +07| +08| +09| +10| +11| +12| +13| +14| My name 1|1|1 +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222221111111111111111 +06|4444444444444444444444441111111111111111 +07|5555555555555555555555551111111111111111 +08|5555555555555555555555551111111111111111 +09|5555555555555555555555551111111111111111 +10|5555555555555555555555551111111111111111 +11|5555555555555555555555551111111111111111 +12|5555555555555555555555551111111111111111 +13|5555555555555555555555551111111111111111 +14|2666666666222222226666661111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---allows-very-large-dimensions b/tests/screenshots/tests-test_pick.lua---Overall-view---allows-very-large-dimensions new file mode 100644 index 00000000..2455022a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---allows-very-large-dimensions @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|┌> ▏───────────────────────────────────┐ +02|│a │ +03|│ │ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└──────────────────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0111000000000000000000000000000000000000 +02|0222222222222222222222222222222222222220 +03|0333333333333333333333333333333333333330 +04|0333333333333333333333333333333333333330 +05|0333333333333333333333333333333333333330 +06|0333333333333333333333333333333333333330 +07|0333333333333333333333333333333333333330 +08|0333333333333333333333333333333333333330 +09|0333333333333333333333333333333333333330 +10|0333333333333333333333333333333333333330 +11|0333333333333333333333333333333333333330 +12|0333333333333333333333333333333333333330 +13|0333333333333333333333333333333333333330 +14|0000000000000000000000000000000000000000 +15|4444444444444444444444444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space b/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space new file mode 100644 index 00000000..7a8d08bc --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|╔> ▏═════════════════════╗ +06|║a ║ +07|║ ║ +08|║ ║ +09|║ ║ +10|║ ║ +11|║ ║ +12|║ ║ +13|║ ║ +14|╚ ══════ 1|1|1 ╝ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2666666666662222226666666211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space-002 b/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space-002 new file mode 100644 index 00000000..44fe96e9 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---correctly-infers-footer-empty-space-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|!> ▏@@@@@@@@@@@@@@@@@@@@@# +06|*a $ +07|* $ +08|* $ +09|* $ +10|* $ +11|* $ +12|* $ +13|* $ +14|& ^^^^^^ 1|1|1 % +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2666666666662222226666666211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---does-not-show-footer-if-items-are-not-set b/tests/screenshots/tests-test_pick.lua---Overall-view---does-not-show-footer-if-items-are-not-set new file mode 100644 index 00000000..fc6b2543 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---does-not-show-footer-if-items-are-not-set @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---is-shown-over-number-and-sign-columns b/tests/screenshots/tests-test_pick.lua---Overall-view---is-shown-over-number-and-sign-columns new file mode 100644 index 00000000..a4530f0f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---is-shown-over-number-and-sign-columns @@ -0,0 +1,23 @@ +--|---------|---------| +01| 1 a +02| 2 b +03|┌> ▏─────────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00111122222222222222 +02|00111122222222222222 +03|34443333333333222222 +04|35555555555553222222 +05|36666666666663222222 +06|36666666666663777777 +07|36666666666663777777 +08|36666666666663777777 +09|33333333333333777777 +10|88888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-`options.content_from_bottom`-with-footer b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-`options.content_from_bottom`-with-footer new file mode 100644 index 00000000..06007daf --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-`options.content_from_bottom`-with-footer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ ────── 1|2|2 ┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│b │ +13|│a │ +14|└> ▏─────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333332222223333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2555555555555555555555555211111111111111 +14|2666222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight' b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight' new file mode 100644 index 00000000..149d4447 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight' @@ -0,0 +1,23 @@ +--|---------|---------| +01| 2 [Scratch] +02| +03|┌> ▏─────────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|└────────────┘ +09|[No Name] +10| + +--|---------|---------| +01|01000000000002222222 +02|33333333333333333333 +03|45554444444444666666 +04|47777777777774666666 +05|48888888888884666666 +06|48888888888884666666 +07|48888888888884666666 +08|44444444444444666666 +09|22222222222222222222 +10|99999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-002 b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-002 new file mode 100644 index 00000000..698c07b0 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01| 2 [Scratch] +02| +03|~ +04|┌> ▏─────────┐ +05|│a │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|01000000000002222222 +02|33333333333333333333 +03|44444444444444444444 +04|56665555555555444444 +05|57777777777775444444 +06|58888888888885444444 +07|58888888888885444444 +08|58888888888885444444 +09|55555555555555444444 +10|99999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-003 b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-003 new file mode 100644 index 00000000..d07ac6cd --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-003 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> ▏─────────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|└────────────┘ +09|[No Name] +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23332222222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|22222222222222111111 +09|66666666666666666666 +10|77777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-004 b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-004 new file mode 100644 index 00000000..8fe3e7fb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-004 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> ▏─────────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23332222222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-005 b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-005 new file mode 100644 index 00000000..4ee5304b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-005 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> ▏─────────┐ +04|│a │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|└────────────┘ + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23332222222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|25555555555552111111 +10|22222222222222111111 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-006 b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-006 new file mode 100644 index 00000000..c12de1b1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---respects-tabline,-statusline,-'cmdheight'-006 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|┌> ▏─────────┐ +03|│a │ +04|│ │ +05|│ │ +06|│ │ +07|└────────────┘ +08| +09| +10| + +--|---------|---------| +01|00000000000000000000 +02|12221111111111333333 +03|14444444444441333333 +04|15555555555551333333 +05|15555555555551333333 +06|15555555555551333333 +07|11111111111111333333 +08|66666666666666666666 +09|66666666666666666666 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt new file mode 100644 index 00000000..1cff0050 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> ▏─────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23332222222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-002 b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-002 new file mode 100644 index 00000000..a247387a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> a▏────────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333222222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-003 b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-003 new file mode 100644 index 00000000..3818cf5a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-003 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> a b▏──────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333332222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-004 b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-004 new file mode 100644 index 00000000..994dd752 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-004 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> a ▏b──────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333332222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-005 b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-005 new file mode 100644 index 00000000..95e43404 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---shows-prompt-005 @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌> a▏ b──────┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333332222222111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|22222222222222111111 +10|66666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text b/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text new file mode 100644 index 00000000..46e8a902 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text @@ -0,0 +1,23 @@ +--|---------|---------| +01| +02|~ +03|┌ long query▏┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└ Very long n┘ +10| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|23333333333332111111 +04|24444444444442111111 +05|25555555555552111111 +06|25555555555552111111 +07|25555555555552111111 +08|25555555555552111111 +09|26666666666662111111 +10|77777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text-002 b/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text-002 new file mode 100644 index 00000000..9ec36f5f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---truncates-border-text-002 @@ -0,0 +1,23 @@ +--|---------|---------|---------|----- +01| +02|~ +03|┌> very long query▏───┐ +04|│ │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└ Very long name ─────┘ +10| + +--|---------|---------|---------|----- +01|00000000000000000000000000000000000 +02|11111111111111111111111111111111111 +03|23333333333333333332222111111111111 +04|24444444444444444444442111111111111 +05|25555555555555555555552111111111111 +06|25555555555555555555552111111111111 +07|25555555555555555555552111111111111 +08|25555555555555555555552111111111111 +09|26666666666666666222222111111111111 +10|77777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info new file mode 100644 index 00000000..c233887a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a │ +07|│b │ +08|│bb │ +09|│bbb │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ──────── 1|4|4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2777777777222222227777777211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-002 b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-002 new file mode 100644 index 00000000..dfe93fee --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│b │ +07|│bb │ +08|│bbb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ──────── 1|3|4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2677777777777777777777777211111111111111 +08|2677777777777777777777777211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2999999999222222229999999211111111111111 +15|:::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-003 b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-003 new file mode 100644 index 00000000..5b514685 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│b │ +07|│bb │ +08|│bbb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ──────── 2|3|4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2677777777777777777777777211111111111111 +08|2455555555555555555555555211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2999999999222222229999999211111111111111 +15|:::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-004 b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-004 new file mode 100644 index 00000000..a272f9e6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-004 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│b │ +07|│bb │ +08|│bbb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ────── 2|3|1/4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2678888888888888888888888211111111111111 +08|2455555555555555555555555211111111111111 +09|2999999999999999999999999211111111111111 +10|2999999999999999999999999211111111111111 +11|2999999999999999999999999211111111111111 +12|2999999999999999999999999211111111111111 +13|2999999999999999999999999211111111111111 +14|2:::::::::222222:::::::::211111111111111 +15|;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-005 b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-005 new file mode 100644 index 00000000..5b514685 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-005 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│b │ +07|│bb │ +08|│bbb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ──────── 2|3|4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2677777777777777777777777211111111111111 +08|2455555555555555555555555211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2999999999222222229999999211111111111111 +15|:::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-006 b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-006 new file mode 100644 index 00000000..687c02b1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Overall-view---uses-footer-for-extra-info-006 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> bx▏───────────────────┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ My name ──────── -|0|4 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333332222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2666666666222222226666666211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label new file mode 100644 index 00000000..e4688350 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|~ +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-002 b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-002 new file mode 100644 index 00000000..e4688350 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-002 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|~ +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-003 b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-003 new file mode 100644 index 00000000..0e6137ef --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-003 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|Line 1 +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|000000000000000 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-004 b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-004 new file mode 100644 index 00000000..6f033978 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---respects-`delay.async`-when-waiting-for-register-label-004 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|Line 1 +03|Line 2 +04|Line 3 +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|000000000000000 +03|000000000000000 +04|000000000000000 +05|122211111113333 +06|144444444413333 +07|155555555513333 +08|155555555513333 +09|155555555513333 +10|155555555513333 +11|155555555513333 +12|155555555513333 +13|155555555513333 +14|111111111113333 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---works b/tests/screenshots/tests-test_pick.lua---Paste---works new file mode 100644 index 00000000..82c1a141 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---works @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> hello▏─┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011111111002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---works-002 b/tests/screenshots/tests-test_pick.lua---Paste---works-002 new file mode 100644 index 00000000..7ddb3bdb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---works-002 @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> ыфя▏───┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011111100002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Paste---works-003 b/tests/screenshots/tests-test_pick.lua---Paste---works-003 new file mode 100644 index 00000000..bfbe4e4a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Paste---works-003 @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> a b c▏─┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011111111002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item b/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item new file mode 100644 index 00000000..45a15b44 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌a───────────────────────┐ +06|│"a" │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item-002 b/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item-002 new file mode 100644 index 00000000..f17cd7ef --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---is-updated-after-moving-current-item-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌b───────────────────────┐ +06|│"b" │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll new file mode 100644 index 00000000..d3f359da --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│1 │ +07|│2 │ +08|│3 │ +09|│4 │ +10|│5 │ +11|│6 │ +12|│7 │ +13|│8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-002 b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-002 new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-003 b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-003 new file mode 100644 index 00000000..fa0b6ed4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 7 │ +07|│Line 8 │ +08|│Line 9 │ +09|│Line 10 │ +10|│Line 11 │ +11|│Line 12 │ +12|│Line 13 │ +13|│Line 14 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-004 b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-004 new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---supports-vertical-and-horizontal-scroll-004 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---Preview---works b/tests/screenshots/tests-test_pick.lua---Preview---works new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Preview---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---Refine---works b/tests/screenshots/tests-test_pick.lua---Refine---works new file mode 100644 index 00000000..30437e58 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Refine---works @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> b▏─────┐ +04|│b │ +05|│ba │ +06|│bb │ +07|│ab │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233332222221111 +04|245555555521111 +05|267777777721111 +06|267777777721111 +07|276777777721111 +08|288888888821111 +09|222222222221111 +10|999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---Refine---works-002 b/tests/screenshots/tests-test_pick.lua---Refine---works-002 new file mode 100644 index 00000000..19dfc943 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Refine---works-002 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│b │ +05|│ba │ +06|│bb │ +07|│ab │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555521111 +06|255555555521111 +07|255555555521111 +08|266666666621111 +09|222222222221111 +10|777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Refine---works-003 b/tests/screenshots/tests-test_pick.lua---Refine---works-003 new file mode 100644 index 00000000..36470220 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Refine---works-003 @@ -0,0 +1,23 @@ +--|---------|----- +01| +02|~ +03|┌> ▏──────┐ +04|│ab │ +05|│ba │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────┘ +10| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|233322222221111 +04|244444444421111 +05|255555555521111 +06|266666666621111 +07|266666666621111 +08|266666666621111 +09|222222222221111 +10|777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---Refine---works-when-no-items-are-set b/tests/screenshots/tests-test_pick.lua---Refine---works-when-no-items-are-set new file mode 100644 index 00000000..626eaca1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---Refine---works-when-no-items-are-set @@ -0,0 +1,13 @@ +-|---------|----- +1|┌> ▏──────┐ +2|│ │ +3|│ │ +4|└─────────┘ +5| + +-|---------|----- +1|011100000002222 +2|033333333304444 +3|055555555504444 +4|000000000004444 +5|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_current` b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_current` new file mode 100644 index 00000000..4abb536c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_current` @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|┌> ▏────────────────────────────────────────┐ +04|│ tests/dir-pick/real-files/b.txt │ +05|│ [No Name] │ +06|│ │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333222222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444444444444444444444421111111111111111111111111 +05|2555555555555555555555555555555555555555555521111111111111111111111111 +06|2666666666666666666666666666666666666666666621111111111111111111111111 +07|2666666666666666666666666666666666666666666621111111111111111111111111 +08|2666666666666666666666666666666666666666666621111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|7777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_unlisted` b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_unlisted` new file mode 100644 index 00000000..85c84fca --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`local_opts.include_unlisted` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ tests/dir-pick/real-f…│ +07|│ [No Name] │ +08|│ [Scratch] │ +09|│ tests/dir-pick/real-f…│ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444445211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666665211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`source.show`-from-config b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`source.show`-from-config new file mode 100644 index 00000000..dc4f5e61 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---respects-`source.show`-from-config @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│tests/dir-pick/real-fil…│ +07|│[No Name] │ +08|│tests/dir-pick/real-fil…│ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444445211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666665211111111111111 +09|2777777777777777777777777211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.buffers()---works b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---works new file mode 100644 index 00000000..0984aad7 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.buffers()---works @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|┌> ▏────────────────────────────────────────┐ +04|│ tests/dir-pick/real-files/b.txt │ +05|│ [No Name] │ +06|│ tests/dir-pick/real-files/LICENSE │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333222222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444444444444444444444421111111111111111111111111 +05|2555555555555555555555555555555555555555555521111111111111111111111111 +06|2555555555555555555555555555555555555555555521111111111111111111111111 +07|2666666666666666666666666666666666666666666621111111111111111111111111 +08|2666666666666666666666666666666666666666666621111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|7777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.files()---respects-`source.show`-from-config b/tests/screenshots/tests-test_pick.lua---builtin.files()---respects-`source.show`-from-config new file mode 100644 index 00000000..0b703377 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.files()---respects-`source.show`-from-config @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> ▏──────────────────────────────────┐ +04|│tests/dir-pick/real-files/b.txt │ +05|│tests/dir-pick │ +06|│ │ +07|│ │ +08|│ │ +09|└─────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------| +01|000000000000000000000000000000000000000000000000000000000000 +02|111111111111111111111111111111111111111111111111111111111111 +03|233322222222222222222222222222222222222111111111111111111111 +04|244444444444444444444444444444444444442111111111111111111111 +05|255555555555555555555555555555555555552111111111111111111111 +06|266666666666666666666666666666666666662111111111111111111111 +07|266666666666666666666666666666666666662111111111111111111111 +08|266666666666666666666666666666666666662111111111111111111111 +09|222222222222222222222222222222222222222111111111111111111111 +10|777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.files()---works b/tests/screenshots/tests-test_pick.lua---builtin.files()---works new file mode 100644 index 00000000..fed04020 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.files()---works @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> ▏──────────────────────────────────┐ +04|│ tests/dir-pick/real-files/b.txt │ +05|│ tests/dir-pick/real-files/LICENSE │ +06|│ tests/dir-pick │ +07|│ │ +08|│ │ +09|└─────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------| +01|000000000000000000000000000000000000000000000000000000000000 +02|111111111111111111111111111111111111111111111111111111111111 +03|233322222222222222222222222222222222222111111111111111111111 +04|244444444444444444444444444444444444442111111111111111111111 +05|255555555555555555555555555555555555552111111111111111111111 +06|266555555555555555555555555555555555552111111111111111111111 +07|277777777777777777777777777777777777772111111111111111111111 +08|277777777777777777777777777777777777772111111111111111111111 +09|222222222222222222222222222222222222222111111111111111111111 +10|888888888888888888888888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.grep()---respects-`source.show`-from-config b/tests/screenshots/tests-test_pick.lua---builtin.grep()---respects-`source.show`-from-config new file mode 100644 index 00000000..06611623 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.grep()---respects-`source.show`-from-config @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> ▏────────────────────────────────────────┐ +04|│tests/dir-pick/real-files/b.txt:1:1 │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333222222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444444444444444444444421111111111111111111111111 +05|2555555555555555555555555555555555555555555521111111111111111111111111 +06|2555555555555555555555555555555555555555555521111111111111111111111111 +07|2555555555555555555555555555555555555555555521111111111111111111111111 +08|2555555555555555555555555555555555555555555521111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|6666666666666666666666666666666666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.grep()---works b/tests/screenshots/tests-test_pick.lua---builtin.grep()---works new file mode 100644 index 00000000..84109e72 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.grep()---works @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> ▏────────────────────────────────────────┐ +04|│ tests/dir-pick/real-files/a.lua:3:3:a │ +05|│ tests/dir-pick/real-files/b.txt:1:1:b │ +06|│ │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333222222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444444444444444444444421111111111111111111111111 +05|2555555555555555555555555555555555555555555521111111111111111111111111 +06|2666666666666666666666666666666666666666666621111111111111111111111111 +07|2666666666666666666666666666666666666666666621111111111111111111111111 +08|2666666666666666666666666666666666666666666621111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|7777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---respects-`source.show`-from-config b/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---respects-`source.show`-from-config new file mode 100644 index 00000000..a43f03e2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---respects-`source.show`-from-config @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> b▏───────────────────────────────────────┐ +04|│tests/dir-pick/real-files/b.txt:1:1 │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333322222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444445444444444444444421111111111111111111111111 +05|2666666666666666666666666666666666666666666621111111111111111111111111 +06|2666666666666666666666666666666666666666666621111111111111111111111111 +07|2666666666666666666666666666666666666666666621111111111111111111111111 +08|2666666666666666666666666666666666666666666621111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|7777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---works b/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---works new file mode 100644 index 00000000..cf4979e6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.grep_live()---works @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|┌> bt▏──────────────────────────────────────┐ +04|│ tests/dir-pick/real-files/b.txt:1:1:b │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└───────────────────────────────────────────┘ +10| + +--|---------|---------|---------|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111111111111111111111111111111111 +03|2333332222222222222222222222222222222222222221111111111111111111111111 +04|2444444444444444444444444444454544444444444421111111111111111111111111 +05|2666666666666666666666666666666666666666666621111111111111111111111111 +06|2666666666666666666666666666666666666666666621111111111111111111111111 +07|2666666666666666666666666666666666666666666621111111111111111111111111 +08|2666666666666666666666666666666666666666666621111111111111111111111111 +09|2222222222222222222222222222222222222222222221111111111111111111111111 +10|7777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---handles-consecutive-applications b/tests/screenshots/tests-test_pick.lua---builtin.help()---handles-consecutive-applications new file mode 100644 index 00000000..4c6bfe18 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---handles-consecutive-applications @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02| :helpg :helpgrep +03|:helpg[rep] {pattern}[@xx] +04| Search all help +05|text files and make a list of lines +06| in which {patter +07|n} matches. Jumps to the first match. +08| The optional [@x +09|x] specifies that only matches in the +10| "xx" language ar +11|e to be found. +12| You can navig@@@ +13|helphelp.txt [Help][RO] +14| +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|0000000000000000111111011111111100000000 +03|0000000000002222222220000000000000000000 +04|0000000000000000000000000000000000000000 +05|0000000000000000000000000000000000000000 +06|0000000000000000000000000000000002222222 +07|2200000000000000000000000000000000000000 +08|0000000000000000000000000000000000000000 +09|0000000000000000000000000000000000000000 +10|0000000000000000000000000000000000000000 +11|0000000000000000000000000000000000000000 +12|0000000000000000000000000000000000000333 +13|4444444444444444444444444444444444444444 +14|0000000000000000000000000000000000000000 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---has-proper-preview b/tests/screenshots/tests-test_pick.lua---builtin.help()---has-proper-preview new file mode 100644 index 00000000..bbac9d2a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---has-proper-preview @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|aa +02|bb +03|aa +04|~ +05|┌!────────────────────────────────────────────────┐ +06|│> > > > > > >│ +07|│!{motion}{filter}> Filter {motion} text line│ +08|│> > > program {filter}. │ +09|│ │ +10|│> > > > > > >│ +11|│!!{filter}> > Filter [count] lines thro│ +12|│> > > {filter}. │ +13|│ │ +14|└─────────────────────────────────────────────────┘ +15| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +03|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|23222222222222222222222222222222222222222222222222211111111111111111111111111111 +06|24444444444444444444444444444444444444444444444444211111111111111111111111111111 +07|25666666666666666644444445555555666666665555555555211111111111111111111111111111 +08|24444444444444444444444445555555566666666555555555211111111111111111111111111111 +09|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +10|24444444444444444444444444444444444444444444444444211111111111111111111111111111 +11|25566666666444444444444445555555666666655555555555211111111111111111111111111111 +12|24444444444444444444444446666666655555555555555555211111111111111111111111111111 +13|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +14|22222222222222222222222222222222222222222222222222211111111111111111111111111111 +15|77777777777777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---works b/tests/screenshots/tests-test_pick.lua---builtin.help()---works new file mode 100644 index 00000000..38e2575d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│! │ +07|│!! │ +08|│# │ +09|│#{} │ +10|│$ │ +11|│$HOME │ +12|│$HOME-windows │ +13|│$MYGVIMRC │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---works-002 b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-002 new file mode 100644 index 00000000..b565e57b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02| ! +03|!{motion}{filter} Filter {motion} +04|text lines through the external +05| program {filter} +06|. +07| +08| +09| !! +10|!!{filter} Filter [count] l +11|ines through the external program +12| {filter}. +13|change.txt [Help][RO] +14| +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|0000000000000000100000000000000000000000 +03|0222222222222222200000000000000222222220 +04|0000000000000000000000000000000000000000 +05|0000000000000000000000000000000022222222 +06|0000000000000000000000000000000000000000 +07|0000000000000000000000000000000000000000 +08|0000000000000000000000000000000000000000 +09|0000000000000000110000000000000000000000 +10|0022222222000000000000000000000222222200 +11|0000000000000000000000000000000000000000 +12|0000000000000000000000002222222200000000 +13|3333333333333333333333333333333333333333 +14|0000000000000000000000000000000000000000 +15|4444444444444444444444444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---works-for-help-tags-with-special-characters b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-for-help-tags-with-special-characters new file mode 100644 index 00000000..a55a4dcf --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-for-help-tags-with-special-characters @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌c_CTRL-K─────────────────────────────────────────┐ +06|│CTRL-K {char1} {char2}> > > > >│ +07|│> > enter digraph (see |digraphs|). │ +08|│> > key, the code for that key is ins│ +09|│ │ +10|│CTRL-R {register}> > > > >│ +11|│> > Insert the contents of a numbered│ +12|│> > typing CTRL-R and the second char│ +13|│> > to indicate that you are expected│ +14|└─────────────────────────────────────────────────┘ +15| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|23333333322222222222222222222222222222222222222222211111111111111111111111111111 +06|24444445444444454444444666666666666666666666666666211111111111111111111111111111 +07|26666666666666666555555555555555555557777777755555211111111111111111111111111111 +08|26666666666666666555555555555555555555555555555555211111111111111111111111111111 +09|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +10|24444445444444444466666666666666666666666666666666211111111111111111111111111111 +11|26666666666666666555555555555555555555555555555555211111111111111111111111111111 +12|26666666666666666555555544444455555555555555555555211111111111111111111111111111 +13|26666666666666666555555555555555555555555555555555211111111111111111111111111111 +14|22222222222222222222222222222222222222222222222222211111111111111111111111111111 +15|88888888888888888888888888888888888888888888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.help()---works-when-help-window-is-alreay-opened b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-when-help-window-is-alreay-opened new file mode 100644 index 00000000..b565e57b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.help()---works-when-help-window-is-alreay-opened @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02| ! +03|!{motion}{filter} Filter {motion} +04|text lines through the external +05| program {filter} +06|. +07| +08| +09| !! +10|!!{filter} Filter [count] l +11|ines through the external program +12| {filter}. +13|change.txt [Help][RO] +14| +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|0000000000000000100000000000000000000000 +03|0222222222222222200000000000000222222220 +04|0000000000000000000000000000000000000000 +05|0000000000000000000000000000000022222222 +06|0000000000000000000000000000000000000000 +07|0000000000000000000000000000000000000000 +08|0000000000000000000000000000000000000000 +09|0000000000000000110000000000000000000000 +10|0022222222000000000000000000000222222200 +11|0000000000000000000000000000000000000000 +12|0000000000000000000000002222222200000000 +13|3333333333333333333333333333333333333333 +14|0000000000000000000000000000000000000000 +15|4444444444444444444444444444444444444444 diff --git a/tests/screenshots/tests-test_pick.lua---builtin.resume()---works b/tests/screenshots/tests-test_pick.lua---builtin.resume()---works new file mode 100644 index 00000000..79d55a64 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---builtin.resume()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│b │ +07|│bb │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2677777777777777777777777211111111111111 +08|2888888888888888888888888211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2222222222222222222222222211111111111111 +15|9999999999999999999999999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---default_match()---does-not-block-query-update b/tests/screenshots/tests-test_pick.lua---default_match()---does-not-block-query-update new file mode 100644 index 00000000..8403b43a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_match()---does-not-block-query-update @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> abc▏──────────────────┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker b/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker new file mode 100644 index 00000000..d5bbc58d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> a▏────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2455555555555555555555555211111111111111 +07|2677777777777777777777777211111111111111 +08|2677777777777777777777777211111111111111 +09|2776777777777777777777777211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2222222222222222222222222211111111111111 +15|9999999999999999999999999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker-002 b/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker-002 new file mode 100644 index 00000000..a53f00c4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_match()---works-with-active-picker-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ab▏───────────────────┐ +06|│abc │ +07|│a_b_c │ +08|│a_b_b │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333332222222222222222222211111111111111 +06|2445555555555555555555555211111111111111 +07|2676777777777777777777777211111111111111 +08|2676777777777777777777777211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2222222222222222222222222211111111111111 +15|9999999999999999999999999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback b/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback new file mode 100644 index 00000000..3795eca0 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|┌-1──────────────────────┐ +04|│-1 │ +05|│ │ +06|│ │ +07|│ │ +08|│ │ +09|└────────────────────────┘ +10| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|2332222222222222222222222211111111111111 +04|2444444444444444444444444211111111111111 +05|2555555555555555555555555211111111111111 +06|2555555555555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2222222222222222222222222211111111111111 +10|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback-002 new file mode 100644 index 00000000..a2d86878 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-fallback-002 @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|┌Random table────────────┐ +04|│{ │ +05|│ text = "Random table" │ +06|│} │ +07|│ │ +08|│ │ +09|└────────────────────────┘ +10| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|2333333333333222222222222211111111111111 +04|2444444444444444444444444211111111111111 +05|2444444444444444444444444211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2222222222222222222222222211111111111111 +10|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer new file mode 100644 index 00000000..5600973b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Tree-sitter highlighting┐ +06|│local a = 1 │ +07|│local t = { │ +08|│ x = math.max(1, 2), │ +09|│ y = math.min(1, 2), │ +10|│} │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444445654575555555555555211111111111111 +07|2444445654585555555555555211111111111111 +08|2556545666686668785788555211111111111111 +09|2556545666686668785788555211111111111111 +10|2855555555555555555555555211111111111111 +11|2999999999999999999999999211111111111111 +12|2999999999999999999999999211111111111111 +13|2999999999999999999999999211111111111111 +14|2222222222222222222222222211111111111111 +15|:::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer-002 new file mode 100644 index 00000000..7d295dfb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-buffer-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Built-in syntax─────────┐ +06|│VAR ?= 1 │ +07|│ │ +08|│all: test │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333222222222211111111111111 +06|2444455555555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2444455555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path new file mode 100644 index 00000000..155ac7f6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/a.lua┐ +06|│local a = 1 │ +07|│local t = { │ +08|│ x = math.max(1, 2), │ +09|│ y = math.min(1, 2), │ +10|│} │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444445654575555555555555211111111111111 +07|2444445654585555555555555211111111111111 +08|2556545666686668785788555211111111111111 +09|2556545666686668785788555211111111111111 +10|2855555555555555555555555211111111111111 +11|2999999999999999999999999211111111111111 +12|2999999999999999999999999211111111111111 +13|2999999999999999999999999211111111111111 +14|2222222222222222222222222211111111111111 +15|:::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path-002 new file mode 100644 index 00000000..9e659e84 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---has-syntax-highlighting-in-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌pick/real-files/Makefile┐ +06|│VAR ?= 1 │ +07|│ │ +08|│all: test │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444455555555555555555555211111111111111 +07|2555555555555555555555555211111111111111 +08|2444455555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer new file mode 100644 index 00000000..3f8d6c60 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-002 new file mode 100644 index 00000000..c1dec34d --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 7 │ +07|│Line 8 │ +08|│Line 9 │ +09|│Line 10 │ +10|│Line 11 │ +11|│Line 12 │ +12|│Line 13 │ +13|│Line 14 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-003 new file mode 100644 index 00000000..c3367e2c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-buffer-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 13 │ +07|│Line 14 │ +08|│Line 15 │ +09|│Line 16 │ +10|│Line 17 │ +11|│Line 18 │ +12|│Line 19 │ +13|│Line 20 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-002 new file mode 100644 index 00000000..fa0b6ed4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 7 │ +07|│Line 8 │ +08|│Line 9 │ +09|│Line 10 │ +10|│Line 11 │ +11|│Line 12 │ +12|│Line 13 │ +13|│Line 14 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-003 new file mode 100644 index 00000000..fb3202b2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---loads-context-in-file-path-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 13 │ +07|│Line 14 │ +08|│Line 15 │ +09|│Line 16 │ +10|│Line 17 │ +11|│Line 18 │ +12|│Line 19 │ +13|│Line 20 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-} b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-} new file mode 100644 index 00000000..cc6dcaa8 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-} @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌pick/real-files/b.txt:10┐ +06|│Line 3 │ +07|│Line 4 │ +08|│Line 5 │ +09|│Line 6 │ +10|│Line 7 │ +11|│Line 8 │ +12|│Line 9 │ +13|│Line 10 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-}-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-}-002 new file mode 100644 index 00000000..2fb8c54f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'bottom'-}-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 5 │ +07|│Line 6 │ +08|│Line 7 │ +09|│Line 8 │ +10|│Line 9 │ +11|│Line 10 │ +12|│Line 11 │ +13|│Line 12 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-} b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-} new file mode 100644 index 00000000..1144c183 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-} @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌pick/real-files/b.txt:10┐ +06|│Line 7 │ +07|│Line 8 │ +08|│Line 9 │ +09|│Line 10 │ +10|│Line 11 │ +11|│Line 12 │ +12|│Line 13 │ +13|│Line 14 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2555555555555555555555555211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-}-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-}-002 new file mode 100644 index 00000000..daf9663a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'center'-}-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 9 │ +07|│Line 10 │ +08|│Line 11 │ +09|│Line 12 │ +10|│Line 13 │ +11|│Line 14 │ +12|│Line 15 │ +13|│Line 16 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2555555555555555555555555211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-} b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-} new file mode 100644 index 00000000..2a0c7e12 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-} @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌pick/real-files/b.txt:10┐ +06|│Line 10 │ +07|│Line 11 │ +08|│Line 12 │ +09|│Line 13 │ +10|│Line 14 │ +11|│Line 15 │ +12|│Line 16 │ +13|│Line 17 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-}-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-}-002 new file mode 100644 index 00000000..c3f7e085 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.line_position`---1-+-args-{-'top'-}-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 12 │ +07|│Line 13 │ +08|│Line 14 │ +09|│Line 15 │ +10|│Line 16 │ +11|│Line 17 │ +12|│Line 18 │ +13|│Line 19 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines` b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines` new file mode 100644 index 00000000..dbdc30bb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌-pick/real-files/b.txt:4┐ +06|│Line 4 │ +07|│Line 5 │ +08|│Line 6 │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines`-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines`-002 new file mode 100644 index 00000000..8ac28907 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`opts.n_context_lines`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer──────────────────┐ +06|│Line 7 │ +07|│Line 8 │ +08|│Line 9 │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`source.cwd` b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`source.cwd` new file mode 100644 index 00000000..809c7665 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---respects-`source.cwd` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌b.txt───────────────────┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333332222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-buffer new file mode 100644 index 00000000..851057f5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Line in buffer──────────┐ +06|│Line 4 in buffer 2 │ +07|│Line 5 in buffer 2 │ +08|│Line 6 in buffer 2 │ +09|│Line 7 in buffer 2 │ +10|│Line 8 in buffer 2 │ +11|│Line 9 in buffer 2 │ +12|│Line 10 in buffer 2 │ +13|│Line 11 in buffer 2 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333332222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path new file mode 100644 index 00000000..8c48dc80 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌-pick/real-files/b.txt:3┐ +06|│Line 3 │ +07|│Line 4 │ +08|│Line 5 │ +09|│Line 6 │ +10|│Line 7 │ +11|│Line 8 │ +12|│Line 9 │ +13|│Line 10 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-002 new file mode 100644 index 00000000..bac4b654 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌files/b.txt:line-in-path┐ +06|│Line 6 │ +07|│Line 7 │ +08|│Line 8 │ +09|│Line 9 │ +10|│Line 10 │ +11|│Line 11 │ +12|│Line 12 │ +13|│Line 13 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-003 new file mode 100644 index 00000000..2d02f989 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-line-in-file-path-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌iles/b.txt:line-separate┐ +06|│Line 8 │ +07|│Line 9 │ +08|│Line 10 │ +09|│Line 11 │ +10|│Line 12 │ +11|│Line 13 │ +12|│Line 14 │ +13|│Line 15 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-buffer new file mode 100644 index 00000000..a305b7e5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Position in buffer──────┐ +06|│Line 6 in buffer 2 │ +07|│Line 7 in buffer 2 │ +08|│Line 8 in buffer 2 │ +09|│Line 9 in buffer 2 │ +10|│Line 10 in buffer 2 │ +11|│Line 11 in buffer 2 │ +12|│Line 12 in buffer 2 │ +13|│Line 13 in buffer 2 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333222222211111111111111 +06|2445444444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path new file mode 100644 index 00000000..876f306c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ick/real-files/b.txt:3:4┐ +06|│Line 3 │ +07|│Line 4 │ +08|│Line 5 │ +09|│Line 6 │ +10|│Line 7 │ +11|│Line 8 │ +12|│Line 9 │ +13|│Line 10 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444544444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-002 new file mode 100644 index 00000000..ffaa22eb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌-files/b.txt:pos-in-path┐ +06|│Line 6 │ +07|│Line 7 │ +08|│Line 8 │ +09|│Line 9 │ +10|│Line 10 │ +11|│Line 11 │ +12|│Line 12 │ +13|│Line 13 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2454444444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-003 new file mode 100644 index 00000000..c2c1f2d0 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-position-in-file-path-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌files/b.txt:pos-separate┐ +06|│Line 8 │ +07|│Line 9 │ +08|│Line 10 │ +09|│Line 11 │ +10|│Line 12 │ +11|│Line 13 │ +12|│Line 14 │ +13|│Line 15 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2445444444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer new file mode 100644 index 00000000..76574da3 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Oneline region in buffer┐ +06|│Line 8 in buffer 2 │ +07|│Line 9 in buffer 2 │ +08|│Line 10 in buffer 2 │ +09|│Line 11 in buffer 2 │ +10|│Line 12 in buffer 2 │ +11|│Line 13 in buffer 2 │ +12|│Line 14 in buffer 2 │ +13|│Line 15 in buffer 2 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2445554444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer-002 new file mode 100644 index 00000000..71d7e594 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-buffer-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌nylines region in buffer┐ +06|│Line 10 in buffer 2 │ +07|│Line 11 in buffer 2 │ +08|│Line 12 in buffer 2 │ +09|│Line 13 in buffer 2 │ +10|│Line 14 in buffer 2 │ +11|│Line 15 in buffer 2 │ +12|│Line 16 in buffer 2 │ +13|│Line 17 in buffer 2 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2445555555555555555544444211111111111111 +07|2666666666666666666677777211111111111111 +08|2666777777777777777777777211111111111111 +09|2777777777777777777777777211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path new file mode 100644 index 00000000..f53eb07f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌les/b.txt:region-oneline┐ +06|│Line 8 │ +07|│Line 9 │ +08|│Line 10 │ +09|│Line 11 │ +10|│Line 12 │ +11|│Line 13 │ +12|│Line 14 │ +13|│Line 15 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2445544444444444444444444211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path-002 new file mode 100644 index 00000000..fda0649f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---shows-region-in-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌s/b.txt:region-manylines┐ +06|│Line 9 │ +07|│Line 10 │ +08|│Line 11 │ +09|│Line 12 │ +10|│Line 13 │ +11|│Line 14 │ +12|│Line 15 │ +13|│Line 16 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2445555444444444444444444211111111111111 +07|2666666677777777777777777211111111111111 +08|2666777777777777777777777211111111111111 +09|2777777777777777777777777211111111111111 +10|2777777777777777777777777211111111111111 +11|2777777777777777777777777211111111111111 +12|2777777777777777777777777211111111111111 +13|2777777777777777777777777211111111111111 +14|2222222222222222222222222211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works b/tests/screenshots/tests-test_pick.lua---default_preview()---works new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer new file mode 100644 index 00000000..e871c0fd --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌2───────────────────────┐ +06|│This is buffer #1 │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-002 new file mode 100644 index 00000000..e871c0fd --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌2───────────────────────┐ +06|│This is buffer #1 │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-003 new file mode 100644 index 00000000..6861330a --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer #2───────────────┐ +06|│This is buffer #2 │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-004 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-004 new file mode 100644 index 00000000..0dd27794 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-004 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer #3───────────────┐ +06|│This is buffer #3 │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-005 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-005 new file mode 100644 index 00000000..90d47094 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-buffer-005 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌Buffer #4───────────────┐ +06|│This is buffer #4 │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path new file mode 100644 index 00000000..6bbde935 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌tests/dir-pick──────────┐ +06|│builtin-tests/ │ +07|│file │ +08|│lua/ │ +09|│mocks/ │ +10|│real-files/ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333332222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path-002 new file mode 100644 index 00000000..a7d6fdcb --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-directory-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ests/dir-pick/real-files┐ +06|│LICENSE │ +07|│Makefile │ +08|│a.lua │ +09|│b.txt │ +10|│c.gif │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path new file mode 100644 index 00000000..042e704c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/b.txt┐ +06|│Line 1 │ +07|│Line 2 │ +08|│Line 3 │ +09|│Line 4 │ +10|│Line 5 │ +11|│Line 6 │ +12|│Line 7 │ +13|│Line 8 │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2444444444444444444444444211111111111111 +14|2222222222222222222222222211111111111111 +15|5555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-002 new file mode 100644 index 00000000..d3d48155 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌-pick/real-files/LICENSE┐ +06|│MIT (c) │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-003 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-003 new file mode 100644 index 00000000..b2851e16 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-for-file-path-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌ir-pick/real-files/c.gif┐ +06|│-Non-text-file- │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333333333333333333333333211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker b/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker new file mode 100644 index 00000000..1e568951 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|Line 1 +02|Line 2 +03|Line 3 +04|Line 4 +05|Line 5 +06|Line 6 +07|Line 7 +08|Line 8 +09|Line 9 +10|Line 10 +11|Line 11 +12|Line 12 +13|Line 13 +14|Line 14 +15| 0,0-1 All + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|0000000000000000000000000000000000000000 +03|0000000000000000000000000000000000000000 +04|0000000000000000000000000000000000000000 +05|0000000000000000000000000000000000000000 +06|0000000000000000000000000000000000000000 +07|0000000000000000000000000000000000000000 +08|0000000000000000000000000000000000000000 +09|0000000000000000000000000000000000000000 +10|0000000000000000000000000000000000000000 +11|0000000000000000000000000000000000000000 +12|0000000000000000000000000000000000000000 +13|0000000000000000000000000000000000000000 +14|0000000000000000000000000000000000000000 +15|1111111111111111111111111111111111111111 diff --git a/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker-002 b/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker-002 new file mode 100644 index 00000000..3f18f999 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_preview()---works-without-active-picker-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|MIT (c) +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| 0,0-1 All + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match` b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match` new file mode 100644 index 00000000..3c0dc8be --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match` @@ -0,0 +1,33 @@ +--|---------|----- +01|abc +02|_abc +03|a_bc +04|ab_c +05|abc_ +06|*abc +07|'abc +08|^abc +09|abc$ +10|a b c +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|----- +01|001111111111111 +02|100111111111111 +03|010111111111111 +04|001111111111111 +05|001111111111111 +06|100111111111111 +07|100111111111111 +08|100111111111111 +09|001111111111111 +10|010111111111111 +11|222222222222222 +12|222222222222222 +13|222222222222222 +14|222222222222222 +15|333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-002 b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-002 new file mode 100644 index 00000000..6c596553 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-002 @@ -0,0 +1,33 @@ +--|---------|----- +01|abc +02|_abc +03|a_bc +04|ab_c +05|abc_ +06|*abc +07|'abc +08|^abc +09|abc$ +10|a b c +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|----- +01|001111111111111 +02|100111111111111 +03|111111111111111 +04|001111111111111 +05|001111111111111 +06|100111111111111 +07|100111111111111 +08|100111111111111 +09|001111111111111 +10|111111111111111 +11|222222222222222 +12|222222222222222 +13|222222222222222 +14|222222222222222 +15|333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-003 b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-003 new file mode 100644 index 00000000..db688c83 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-003 @@ -0,0 +1,33 @@ +--|---------|----- +01|abc +02|_abc +03|a_bc +04|ab_c +05|abc_ +06|*abc +07|'abc +08|^abc +09|abc$ +10|a b c +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|----- +01|001111111111111 +02|111111111111111 +03|111111111111111 +04|001111111111111 +05|001111111111111 +06|111111111111111 +07|111111111111111 +08|111111111111111 +09|001111111111111 +10|111111111111111 +11|222222222222222 +12|222222222222222 +13|222222222222222 +14|222222222222222 +15|333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-004 b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-004 new file mode 100644 index 00000000..533ddacf --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-004 @@ -0,0 +1,33 @@ +--|---------|----- +01|abc +02|_abc +03|a_bc +04|ab_c +05|abc_ +06|*abc +07|'abc +08|^abc +09|abc$ +10|a b c +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|----- +01|011000000000000 +02|001100000000000 +03|001100000000000 +04|000000000000000 +05|000000000000000 +06|001100000000000 +07|001100000000000 +08|001100000000000 +09|000000000000000 +10|000000000000000 +11|222222222222222 +12|222222222222222 +13|222222222222222 +14|222222222222222 +15|333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-005 b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-005 new file mode 100644 index 00000000..5388dc9e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-query-similar-to-`default_match`-005 @@ -0,0 +1,33 @@ +--|---------|----- +01|abc +02|_abc +03|a_bc +04|ab_c +05|abc_ +06|*abc +07|'abc +08|^abc +09|abc$ +10|a b c +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|----- +01|000111111111111 +02|100011111111111 +03|111111111111111 +04|001011111111111 +05|000111111111111 +06|100011111111111 +07|100011111111111 +08|100011111111111 +09|000111111111111 +10|111111111111111 +11|222222222222222 +12|222222222222222 +13|222222222222222 +14|222222222222222 +15|333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---handles-stritems-with-non-trivial-whitespace b/tests/screenshots/tests-test_pick.lua---default_show()---handles-stritems-with-non-trivial-whitespace new file mode 100644 index 00000000..d02c5faa --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---handles-stritems-with-non-trivial-whitespace @@ -0,0 +1,23 @@ +--|---------|---------| +01|With newline +02|With tab +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|00000000000000000000 +02|00000000000000000000 +03|11111111111111111111 +04|11111111111111111111 +05|11111111111111111111 +06|11111111111111111111 +07|11111111111111111111 +08|11111111111111111111 +09|11111111111111111111 +10|22222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase' b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase' new file mode 100644 index 00000000..b520ded1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase' @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|010111111111 +2|111111111111 +3|111111111111 +4|111111111111 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-002 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-002 new file mode 100644 index 00000000..ed29ea6f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-002 @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|000000000000 +2|101000000000 +3|000000000000 +4|000000000000 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-003 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-003 new file mode 100644 index 00000000..241ca281 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-003 @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|010111111111 +2|010111111111 +3|010111111111 +4|010111111111 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-004 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-004 new file mode 100644 index 00000000..241ca281 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-004 @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|010111111111 +2|010111111111 +3|010111111111 +4|010111111111 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-005 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-005 new file mode 100644 index 00000000..241ca281 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-005 @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|010111111111 +2|010111111111 +3|010111111111 +4|010111111111 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-006 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-006 new file mode 100644 index 00000000..ed29ea6f --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-'ignorecase'-'smartcase'-006 @@ -0,0 +1,17 @@ +-|---------|-- +1|a_b +2|a_B +3|A_b +4|A_B +5|~ +6|~ +7| + +-|---------|-- +1|000000000000 +2|101000000000 +3|000000000000 +4|000000000000 +5|222222222222 +6|222222222222 +7|333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons` b/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons` new file mode 100644 index 00000000..e155c279 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons` @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|----- +01| tests/dir-pick/real-files/LICENSE +02| tests/dir-pick/real-files/Makefile +03| tests/dir-pick/real-files/a.lua +04| tests/dir-pick/real-files/b.txt +05| tests/dir-pick/real-files/c.gif +06| tests/dir-pick +07| non-existing +08| non-string +09|~ +10| + +--|---------|---------|---------|---------|----- +01|001111111211121111111111111111111111111111111 +02|001111111211121111111111111111111111111111111 +03|001111111211121111111111111111111111111111111 +04|001111111211121111111111111111111111111111111 +05|001111111211121111111111111111111111111111111 +06|331111111211121111111111111111111111111111111 +07|001111112112111111111111111111111111111111111 +08|001111111111111111111111111111111111111111111 +09|444444444444444444444444444444444444444444444 +10|555555555555555555555555555555555555555555555 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons`-002 b/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons`-002 new file mode 100644 index 00000000..3d03d7e4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---respects-`opts.show_icons`-002 @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------|----- +01| tests/dir-pick/real-files/LICENSE +02| tests/dir-pick/real-files/Makefile +03| tests/dir-pick/real-files/a.lua +04| tests/dir-pick/real-files/b.txt +05| tests/dir-pick/real-files/c.gif +06| tests/dir-pick +07| non-existing +08| non-string +09|~ +10| + +--|---------|---------|---------|---------|----- +01|001111111211121111111111111111111111111111111 +02|331111111211121111111111111111111111111111111 +03|441111111211121111111111111111111111111111111 +04|551111111211121111111111111111111111111111111 +05|661111111211121111111111111111111111111111111 +06|771111111211121111111111111111111111111111111 +07|881111112112111111111111111111111111111111111 +08|881111111111111111111111111111111111111111111 +09|999999999999999999999999999999999999999999999 +10|::::::::::::::::::::::::::::::::::::::::::::: diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match b/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match new file mode 100644 index 00000000..8649b0b2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match @@ -0,0 +1,23 @@ +--|---------|---------| +01|a__b_a__b_ab +02|a__b_ab_a__b +03|ab_a__b_a__b +04|ab__ab +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|00000000001100000000 +02|00000110000000000000 +03|11000000000000000000 +04|11000000000000000000 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match-002 b/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match-002 new file mode 100644 index 00000000..2e5d2ded --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---shows-best-match-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01|aabbccddee +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|01101010100000000000 +02|22222222222222222222 +03|22222222222222222222 +04|22222222222222222222 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works b/tests/screenshots/tests-test_pick.lua---default_show()---works new file mode 100644 index 00000000..d5ce3b25 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ab▏───────────────────┐ +06|│abc │ +07|│a_bc │ +08|│a__bc │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333332222222222222222222211111111111111 +06|2445555555555555555555555211111111111111 +07|2676777777777777777777777211111111111111 +08|2677677777777777777777777211111111111111 +09|2888888888888888888888888211111111111111 +10|2888888888888888888888888211111111111111 +11|2888888888888888888888888211111111111111 +12|2888888888888888888888888211111111111111 +13|2888888888888888888888888211111111111111 +14|2222222222222222222222222211111111111111 +15|9999999999999999999999999999999999999999 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters new file mode 100644 index 00000000..646111d4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters @@ -0,0 +1,23 @@ +--|---------|---------| +01|ыdф +02|ыы_d_ф +03|_ыы_d_ф +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|01011111111111111111 +02|10111011111111111111 +03|11011101111111111111 +04|22222222222222222222 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters-002 b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters-002 new file mode 100644 index 00000000..ecf48209 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-multibyte-characters-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01|ыdф +02|ыы_d_ф +03|_ыы_d_ф +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|01000000000000000000 +02|00010000000000000000 +03|00001000000000000000 +04|22222222222222222222 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries new file mode 100644 index 00000000..48763d82 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries @@ -0,0 +1,23 @@ +--|---------|---------| +01|_abc +02|a_bc +03|ab_c +04|abc_ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|01110000000000000000 +02|00000000000000000000 +03|11010000000000000000 +04|11100000000000000000 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-002 b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-002 new file mode 100644 index 00000000..5e6844bf --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01|_abc +02|a_bc +03|ab_c +04|abc_ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|01110000000000000000 +02|00000000000000000000 +03|00000000000000000000 +04|11100000000000000000 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-003 b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-003 new file mode 100644 index 00000000..f94d4e06 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-with-non-single-char-entries-queries-003 @@ -0,0 +1,23 @@ +--|---------|---------| +01|_abc +02|a_bc +03|ab_c +04|abc_ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|00000000000000000000 +02|00000000000000000000 +03|00000000000000000000 +04|00000000000000000000 +05|11111111111111111111 +06|11111111111111111111 +07|11111111111111111111 +08|11111111111111111111 +09|11111111111111111111 +10|22222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker b/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker new file mode 100644 index 00000000..275389e1 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker @@ -0,0 +1,23 @@ +--|---------|---------| +01|abc +02|a_bc +03|a__bc +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|00111111111111111111 +02|01011111111111111111 +03|01101111111111111111 +04|22222222222222222222 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker-002 b/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker-002 new file mode 100644 index 00000000..b5443a89 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---default_show()---works-without-active-picker-002 @@ -0,0 +1,23 @@ +--|---------|---------| +01|def +02|d_ef +03|d__ef +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10| + +--|---------|---------| +01|00111111111111111111 +02|01011111111111111111 +03|01101111111111111111 +04|22222222222222222222 +05|22222222222222222222 +06|22222222222222222222 +07|22222222222222222222 +08|22222222222222222222 +09|22222222222222222222 +10|33333333333333333333 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized` b/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized` new file mode 100644 index 00000000..3169f3c5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized`-002 b/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized`-002 new file mode 100644 index 00000000..b3f0d63c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---is-called-on-`VimResized`-002 @@ -0,0 +1,33 @@ +--|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────┘ +15| + +--|---------|---------| +01|00000000000000000000 +02|11111111111111111111 +03|11111111111111111111 +04|11111111111111111111 +05|23332222222222111111 +06|24444444444442111111 +07|25555555555552111111 +08|25555555555552111111 +09|25555555555552111111 +10|25555555555552111111 +11|26666666666662111111 +12|26666666666662111111 +13|26666666666662111111 +14|22222222222222111111 +15|77777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config b/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config new file mode 100644 index 00000000..9c3a8767 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏───────┐ +06|│a │ +07|│b │ +08|│c │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└──────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222221111111111111111111111111111 +06|2444444444421111111111111111111111111111 +07|2555555555521111111111111111111111111111 +08|2555555555521111111111111111111111111111 +09|2666666666621111111111111111111111111111 +10|2666666666621111111111111111111111111111 +11|2666666666621111111111111111111111111111 +12|2666666666621111111111111111111111111111 +13|2666666666621111111111111111111111111111 +14|2222222222221111111111111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config-002 b/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config-002 new file mode 100644 index 00000000..c91e32c2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---recomputes-window-config-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────┐ +06|│a │ +07|│b │ +08|│c │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222111111111111111111 +06|2444444444444444444442111111111111111111 +07|2555555555555555555552111111111111111111 +08|2555555555555555555552111111111111111111 +09|2666666666666666666662111111111111111111 +10|2666666666666666666662111111111111111111 +11|2666666666666666666662111111111111111111 +12|2666666666666666666662111111111111111111 +13|2666666666666666666662111111111111111111 +14|2222222222222222222222111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---works b/tests/screenshots/tests-test_pick.lua---refresh()---works new file mode 100644 index 00000000..3169f3c5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---refresh()---works-002 b/tests/screenshots/tests-test_pick.lua---refresh()---works-002 new file mode 100644 index 00000000..677c111c --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---refresh()---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏───────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└──────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222221111111111111111111111111111 +06|2444444444421111111111111111111111111111 +07|2555555555521111111111111111111111111111 +08|2555555555521111111111111111111111111111 +09|2555555555521111111111111111111111111111 +10|2555555555521111111111111111111111111111 +11|2666666666621111111111111111111111111111 +12|2666666666621111111111111111111111111111 +13|2666666666621111111111111111111111111111 +14|2222222222221111111111111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---set_picker_match_inds()---works b/tests/screenshots/tests-test_pick.lua---set_picker_match_inds()---works new file mode 100644 index 00000000..81ccab65 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---set_picker_match_inds()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│b │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works new file mode 100644 index 00000000..57fd07e9 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a │ +07|│b │ +08|│bb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ ────── 1|3|3 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2777777777772222227777777211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-002 b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-002 new file mode 100644 index 00000000..b0824cbd --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ ┌> ▏─────────────────────┐ +06|~ │a │ +07|~ │b │ +08|~ │bb │ +09|~ │ │ +10|~ │ │ +11|~ │ │ +12|~ │ │ +13|~ │ │ +14|~ └ My name ──────── 1|3|3 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111123332222222222222222222222111111111 +06|1111124444444444444444444444442111111111 +07|1111125555555555555555555555552111111111 +08|1111125555555555555555555555552111111111 +09|1111126666666666666666666666662111111111 +10|1111126666666666666666666666662111111111 +11|1111126666666666666666666666662111111111 +12|1111126666666666666666666666662111111111 +13|1111126666666666666666666666662111111111 +14|1111127777777772222222277777772111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-003 b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-003 new file mode 100644 index 00000000..2a8fdce5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---set_picker_opts()---works-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ ┌> ▏─────────────────────┐ +06|~ │b │ +07|~ │ │ +08|~ │ │ +09|~ │ │ +10|~ │ │ +11|~ │ │ +12|~ │ │ +13|~ │ │ +14|~ └ My name ──────── 1|1|3 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111123332222222222222222222222111111111 +06|1111124444444444444444444444442111111111 +07|1111125555555555555555555555552111111111 +08|1111125555555555555555555555552111111111 +09|1111125555555555555555555555552111111111 +10|1111125555555555555555555555552111111111 +11|1111125555555555555555555555552111111111 +12|1111125555555555555555555555552111111111 +13|1111125555555555555555555555552111111111 +14|1111126666666662222222266666662111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---set_picker_query()---works b/tests/screenshots/tests-test_pick.lua---set_picker_query()---works new file mode 100644 index 00000000..1ffbde0b --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---set_picker_query()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> bb▏───────────────────┐ +06|│bb │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333332222222222222222222211111111111111 +06|2445555555555555555555555211111111111111 +07|2666666666666666666666666211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---can-be-started-without-explicit-items b/tests/screenshots/tests-test_pick.lua---start()---can-be-started-without-explicit-items new file mode 100644 index 00000000..fc6b2543 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---can-be-started-without-explicit-items @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---correctly-computes-stritems b/tests/screenshots/tests-test_pick.lua---start()---correctly-computes-stritems new file mode 100644 index 00000000..961b2c85 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---correctly-computes-stritems @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏──────────────────────────────────────────────┐ +06|│string_item │ +07|│table_item │ +08|│{ a = "fallback item", b = 1 } │ +09|│string_item_from_callable │ +10|│table_item_from_callable │ +11|│{ c = "fallback item from callable", d = 1 } │ +12|│ │ +13|│ │ +14|└─────────────────────────────────────────────────┘ +15| + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|23332222222222222222222222222222222222222222222222211111111111111111111111111111 +06|24444444444444444444444444444444444444444444444444211111111111111111111111111111 +07|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +08|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +09|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +10|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +11|25555555555555555555555555555555555555555555555555211111111111111111111111111111 +12|26666666666666666666666666666666666666666666666666211111111111111111111111111111 +13|26666666666666666666666666666666666666666666666666211111111111111111111111111111 +14|22222222222222222222222222222222222222222222222222211111111111111111111111111111 +15|77777777777777777777777777777777777777777777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async` b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async` new file mode 100644 index 00000000..e4688350 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async` @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|~ +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-002 b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-002 new file mode 100644 index 00000000..e4688350 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-002 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|~ +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|111111111111111 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-003 b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-003 new file mode 100644 index 00000000..0e6137ef --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-003 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|Line 1 +03|~ +04|~ +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|000000000000000 +03|111111111111111 +04|111111111111111 +05|233322222221111 +06|244444444421111 +07|255555555521111 +08|255555555521111 +09|255555555521111 +10|255555555521111 +11|255555555521111 +12|255555555521111 +13|255555555521111 +14|222222222221111 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-004 b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-004 new file mode 100644 index 00000000..6f033978 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`delay.async`-004 @@ -0,0 +1,33 @@ +--|---------|----- +01| +02|Line 1 +03|Line 2 +04|Line 3 +05|┌> ▏──────┐ +06|│a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└─────────┘ +15| + +--|---------|----- +01|000000000000000 +02|000000000000000 +03|000000000000000 +04|000000000000000 +05|122211111113333 +06|144444444413333 +07|155555555513333 +08|155555555513333 +09|155555555513333 +10|155555555513333 +11|155555555513333 +12|155555555513333 +13|155555555513333 +14|111111111113333 +15|666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`options.content_from_bottom` b/tests/screenshots/tests-test_pick.lua---start()---respects-`options.content_from_bottom` new file mode 100644 index 00000000..063c7301 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`options.content_from_bottom` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│b │ +13|│a │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2444444444444444444444444211111111111111 +12|2444444444444444444444444211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items` b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items` new file mode 100644 index 00000000..2a20c5ee --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a │ +07|│b │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-002 b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-002 new file mode 100644 index 00000000..5f49dcf2 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│c │ +07|│d │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-003 b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-003 new file mode 100644 index 00000000..249ad5b6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-003 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│e │ +07|│f │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-004 b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-004 new file mode 100644 index 00000000..4d1beef0 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.items`-004 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│g │ +07|│h │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.match` b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.match` new file mode 100644 index 00000000..81ccab65 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.match` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│b │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.name` b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.name` new file mode 100644 index 00000000..cea53e85 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.name` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└ Hello ────────── 1|5|5 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2777777722222222227777777211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview` b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview` new file mode 100644 index 00000000..f517f1a4 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌a───────────────────────┐ +06|│Preview: a │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview`-002 b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview`-002 new file mode 100644 index 00000000..5d8249a3 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.preview`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌b───────────────────────┐ +06|│Preview: b │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2322222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show` b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show` new file mode 100644 index 00000000..1aa447b6 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│__a │ +07|│__b │ +08|│__bb │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show`-002 b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show`-002 new file mode 100644 index 00000000..b15c7712 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`source.show`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> b▏────────────────────┐ +06|│__b │ +07|│__bb │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333322222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`vim.b.minipick_config` b/tests/screenshots/tests-test_pick.lua---start()---respects-`vim.b.minipick_config` new file mode 100644 index 00000000..650d2294 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`vim.b.minipick_config` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|┌> ▏───────┐ +05|│a │ +06|│b │ +07|│c │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|└──────────┘ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|2333222222221111111111111111111111111111 +05|2444444444421111111111111111111111111111 +06|2555555555521111111111111111111111111111 +07|2555555555521111111111111111111111111111 +08|2666666666621111111111111111111111111111 +09|2666666666621111111111111111111111111111 +10|2666666666621111111111111111111111111111 +11|2666666666621111111111111111111111111111 +12|2666666666621111111111111111111111111111 +13|2222222222221111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config` b/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config` new file mode 100644 index 00000000..2989be76 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|╔> ▏═════════════════════╗ +06|║a ║ +07|║b ║ +08|║c ║ +09|║ ║ +10|║ ║ +11|║ ║ +12|║ ║ +13|║ ║ +14|╚════════════════════════╝ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config`-002 b/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config`-002 new file mode 100644 index 00000000..dc707a87 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-`window.config`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|┌> ▏───────────────────────────────────┐ +04|│a │ +05|│b │ +06|│c │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|└──────────────────────────────────────┘ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|2333222222222222222222222222222222222222 +04|2444444444444444444444444444444444444442 +05|2555555555555555555555555555555555555552 +06|2555555555555555555555555555555555555552 +07|2666666666666666666666666666666666666662 +08|2666666666666666666666666666666666666662 +09|2666666666666666666666666666666666666662 +10|2666666666666666666666666666666666666662 +11|2666666666666666666666666666666666666662 +12|2222222222222222222222222222222222222222 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---respects-global-config b/tests/screenshots/tests-test_pick.lua---start()---respects-global-config new file mode 100644 index 00000000..5b1e6a86 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---respects-global-config @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|┌> ▏─────────────────────┐ +03|│a │ +04|│b │ +05|│c │ +06|│ │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|└────────────────────────┘ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1222111111111111111111111133333333333333 +03|1444444444444444444444444133333333333333 +04|1555555555555555555555555133333333333333 +05|1555555555555555555555555133333333333333 +06|1666666666666666666666666133333333333333 +07|1666666666666666666666666133333333333333 +08|1666666666666666666666666133333333333333 +09|1666666666666666666666666133333333333333 +10|1666666666666666666666666133333333333333 +11|1111111111111111111111111133333333333333 +12|3333333333333333333333333333333333333333 +13|3333333333333333333333333333333333333333 +14|3333333333333333333333333333333333333333 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---stops-currently-active-picker b/tests/screenshots/tests-test_pick.lua---start()---stops-currently-active-picker new file mode 100644 index 00000000..d0f11276 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---stops-currently-active-picker @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│d │ +07|│e │ +08|│f │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker b/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker new file mode 100644 index 00000000..502f2d7e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a │ +07|│b │ +08|│c │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker-002 b/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker-002 new file mode 100644 index 00000000..02dd2bfd --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---stops-impoperly-aborted-previous-picker-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏───────┐ +06|│d │ +07|│e │ +08|│f │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└──────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222221111111111111111111111111111 +06|2444444444421111111111111111111111111111 +07|2555555555521111111111111111111111111111 +08|2555555555521111111111111111111111111111 +09|2666666666621111111111111111111111111111 +10|2666666666621111111111111111111111111111 +11|2666666666621111111111111111111111111111 +12|2666666666621111111111111111111111111111 +13|2666666666621111111111111111111111111111 +14|2222222222221111111111111111111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus b/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus new file mode 100644 index 00000000..2a20c5ee --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a │ +07|│b │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus-002 b/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus-002 new file mode 100644 index 00000000..10f70585 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---tracks-lost-focus-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works b/tests/screenshots/tests-test_pick.lua---start()---works new file mode 100644 index 00000000..3169f3c5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works-002 b/tests/screenshots/tests-test_pick.lua---start()---works-002 new file mode 100644 index 00000000..cfdfd56e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|"a_b_c" + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9 b/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9 new file mode 100644 index 00000000..5ba72069 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌────────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2222222222222222222222222211111111111111 +06|2333333333333333333333333211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2444444444444444444444444211111111111111 +10|2444444444444444444444444211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9-002 b/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9-002 new file mode 100644 index 00000000..cfdfd56e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works-on-Neovim-0.9-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|"a_b_c" + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer b/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer new file mode 100644 index 00000000..def5918e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└ ────── 1|5|5 ┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2777777777772222227777777211111111111111 +15|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer-002 b/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer-002 new file mode 100644 index 00000000..cfdfd56e --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---start()---works-with-window-footer-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15|"a_b_c" + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---stop()---works b/tests/screenshots/tests-test_pick.lua---stop()---works new file mode 100644 index 00000000..3169f3c5 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---stop()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│a_b_c │ +07|│abc │ +08|│a_b_b │ +09|│c_a_a │ +10|│b_c_c │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/screenshots/tests-test_pick.lua---stop()---works-002 b/tests/screenshots/tests-test_pick.lua---stop()---works-002 new file mode 100644 index 00000000..10f70585 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---stop()---works-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111111111111111111111111111111111111 +07|1111111111111111111111111111111111111111 +08|1111111111111111111111111111111111111111 +09|1111111111111111111111111111111111111111 +10|1111111111111111111111111111111111111111 +11|1111111111111111111111111111111111111111 +12|1111111111111111111111111111111111111111 +13|1111111111111111111111111111111111111111 +14|1111111111111111111111111111111111111111 +15|2222222222222222222222222222222222222222 diff --git a/tests/screenshots/tests-test_pick.lua---ui_select()---respects-`opts.preview_item` b/tests/screenshots/tests-test_pick.lua---ui_select()---respects-`opts.preview_item` new file mode 100644 index 00000000..f456f6cf --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---ui_select()---respects-`opts.preview_item` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌abc─────────────────────┐ +06|│My preview │ +07|│Var = abc │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2555555555555555555555555211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---ui_select()---shows-only-original-item-in-preview b/tests/screenshots/tests-test_pick.lua---ui_select()---shows-only-original-item-in-preview new file mode 100644 index 00000000..374e2973 --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---ui_select()---shows-only-original-item-in-preview @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌abc─────────────────────┐ +06|│{ │ +07|│ var = "abc" │ +08|│} │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2444444444444444444444444211111111111111 +08|2444444444444444444444444211111111111111 +09|2555555555555555555555555211111111111111 +10|2555555555555555555555555211111111111111 +11|2555555555555555555555555211111111111111 +12|2555555555555555555555555211111111111111 +13|2555555555555555555555555211111111111111 +14|2222222222222222222222222211111111111111 +15|6666666666666666666666666666666666666666 diff --git a/tests/screenshots/tests-test_pick.lua---ui_select()---works b/tests/screenshots/tests-test_pick.lua---ui_select()---works new file mode 100644 index 00000000..c4930fff --- /dev/null +++ b/tests/screenshots/tests-test_pick.lua---ui_select()---works @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|┌> ▏─────────────────────┐ +06|│-1 │ +07|│-2 │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└────────────────────────┘ +15| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|2333222222222222222222222211111111111111 +06|2444444444444444444444444211111111111111 +07|2555555555555555555555555211111111111111 +08|2666666666666666666666666211111111111111 +09|2666666666666666666666666211111111111111 +10|2666666666666666666666666211111111111111 +11|2666666666666666666666666211111111111111 +12|2666666666666666666666666211111111111111 +13|2666666666666666666666666211111111111111 +14|2222222222222222222222222211111111111111 +15|7777777777777777777777777777777777777777 diff --git a/tests/test_pick.lua b/tests/test_pick.lua new file mode 100644 index 00000000..9817621c --- /dev/null +++ b/tests/test_pick.lua @@ -0,0 +1,4994 @@ +local helpers = dofile('tests/helpers.lua') + +local child = helpers.new_child_neovim() +local expect, eq = helpers.expect, helpers.expect.equality +local new_set = MiniTest.new_set + +-- Helpers with child processes +--stylua: ignore start +local load_module = function(config) child.mini_load('pick', config) end +local unload_module = function() child.mini_unload('pick') end +local set_cursor = function(...) return child.set_cursor(...) end +local get_cursor = function(...) return child.get_cursor(...) end +local type_keys = function(...) return child.type_keys(...) end +local poke_eventloop = function() child.api.nvim_eval('1') end +local sleep = function(ms) vim.loop.sleep(ms); poke_eventloop() end +--stylua: ignore end + +-- Tweak `expect_screenshot()` to test only on Neovim=0.9 (as it introduced +-- titles and 0.10 introduced footer). +-- Use `child.expect_screenshot_orig()` for original testing. +child.expect_screenshot_orig = child.expect_screenshot +child.expect_screenshot = function(opts, allow_past_09) + -- TODO: Regenerate all screenshots with 0.10 after its stable release + if child.fn.has('nvim-0.9') == 0 or child.fn.has('nvim-0.10') == 1 then return end + child.expect_screenshot_orig(opts) +end + +child.has_float_footer = function() + -- https://github.com/neovim/neovim/pull/24739 + return child.fn.has('nvim-0.10') == 1 +end + +-- Test paths helpers +local test_dir = 'tests/dir-pick' +local real_files_dir = 'tests/dir-pick/real-files' + +local join_path = function(...) return table.concat({ ... }, '/') end + +local full_path = function(x) + local res = vim.fn.fnamemodify(x, ':p'):gsub('/$', '') + return res +end + +local real_file = function(basename) return join_path(real_files_dir, basename) end + +local setup_windows_pair = function() + child.cmd('botright wincmd v') + local win_id_1 = child.api.nvim_get_current_win() + child.cmd('wincmd h') + local win_id_2 = child.api.nvim_get_current_win() + child.api.nvim_set_current_win(win_id_1) + return win_id_1, win_id_2 +end + +-- Common test wrappers +local forward_lua = function(fun_str) + local lua_cmd = fun_str .. '(...)' + return function(...) return child.lua_get(lua_cmd, { ... }) end +end + +local forward_lua_notify = function(fun_str) + local lua_cmd = fun_str .. '(...)' + return function(...) return child.lua_notify(lua_cmd, { ... }) end +end + +local stop = forward_lua('MiniPick.stop') +local get_picker_items = forward_lua('MiniPick.get_picker_items') +local get_picker_stritems = forward_lua('MiniPick.get_picker_stritems') +local get_picker_matches = forward_lua('MiniPick.get_picker_matches') +local get_picker_state = forward_lua('MiniPick.get_picker_state') +local get_picker_query = forward_lua('MiniPick.get_picker_query') +local set_picker_items = forward_lua('MiniPick.set_picker_items') +local set_picker_query = forward_lua('MiniPick.set_picker_query') +local get_querytick = forward_lua('MiniPick.get_querytick') +local is_picker_active = forward_lua('MiniPick.is_picker_active') + +-- Use `child.api_notify` to allow user input while child process awaits for +-- `start()` to return a value +local start = function(...) child.lua_notify('MiniPick.start(...)', { ... }) end + +local start_with_items = function(items, name) start({ source = { items = items, name = name } }) end + +-- Common test helpers +local validate_buf_option = + function(buf_id, option_name, option_value) eq(child.api.nvim_buf_get_option(buf_id, option_name), option_value) end + +local validate_win_option = + function(win_id, option_name, option_value) eq(child.api.nvim_win_get_option(win_id, option_name), option_value) end + +local validate_buf_name = function(buf_id, name) + buf_id = buf_id or child.api.nvim_get_current_buf() + name = name ~= '' and full_path(name) or '' + name = name:gsub('/+$', '') + eq(child.api.nvim_buf_get_name(buf_id), name) +end + +local validate_contains_all = function(base, to_be_present) + local is_present_map, is_all_present = {}, true + for _, x in pairs(to_be_present) do + is_present_map[x] = vim.tbl_contains(base, x) + is_all_present = is_all_present and is_present_map[x] + end + if is_all_present then return end + local err_msg = string.format( + 'Not all elements are present:\nActual: %s\nReference map: %s', + vim.inspect(base), + vim.inspect(is_present_map) + ) + error(err_msg) +end + +local validate_picker_option = function(string_index, ref) + local value = child.lua_get('MiniPick.get_picker_opts().' .. string_index) + eq(value, ref) +end + +local validate_picker_view = + function(view_name) eq(child.api.nvim_get_current_buf(), get_picker_state().buffers[view_name]) end + +local validate_current_ind = function(ref_ind) eq(get_picker_matches().current_ind, ref_ind) end + +local seq_along = function(x) + local res = {} + for i = 1, #x do + res[i] = i + end + return res +end + +local make_match_with_count = function() + child.lua('_G.match_n_calls = 0') + local validate_match_calls = function(n_calls_ref, match_inds_ref) + eq(child.lua_get('_G.match_n_calls'), n_calls_ref) + eq(get_picker_matches().all_inds, match_inds_ref) + end + + child.lua_notify([[_G.match_with_count = function(...) + _G.match_n_calls = _G.match_n_calls + 1 + return MiniPick.default_match(...) + end]]) + return validate_match_calls +end + +local make_event_log = function() + child.lua([[ + _G.event_log = {} + _G.track_event = function() + local buf_id = MiniPick.get_picker_state().buffers.main + local entry + if not vim.api.nvim_buf_is_valid(buf_id) then + entry = 'Main buffer is invalid' + else + entry = #vim.api.nvim_buf_get_lines(buf_id, 0, -1, false) + end + table.insert(_G.event_log, entry) + end]]) +end + +-- Common mocks +local mock_fn_executable = function(available_executables) + local lua_cmd = string.format( + 'vim.fn.executable = function(x) return vim.tbl_contains(%s, x) and 1 or 0 end', + vim.inspect(available_executables) + ) + child.lua(lua_cmd) +end + +local mock_picker_cwd = function(cwd) + child.lua('vim.fn.fnamemodify = function(x) return x end') + child.lua(string.format('MiniPick.set_picker_opts({ source = { cwd = %s } })', vim.inspect(cwd))) +end + +local mock_spawn = function() + local mock_file = join_path(test_dir, 'mocks', 'spawn.lua') + local lua_cmd = string.format('dofile(%s)', vim.inspect(mock_file)) + child.lua(lua_cmd) +end + +local mock_stdout_feed = function(feed) child.lua('_G.stdout_data_feed = ' .. vim.inspect(feed)) end + +local mock_cli_return = function(items) mock_stdout_feed({ table.concat(items, '\n') }) end + +local get_spawn_log = function() return child.lua_get('_G.spawn_log') end + +local clear_spawn_log = function() child.lua('_G.spawn_log = {}') end + +local validate_spawn_log = function(ref, index) + local present = get_spawn_log() + if type(index) == 'number' then present = present[index] end + eq(present, ref) +end + +local get_process_log = function() return child.lua_get('_G.process_log') end + +local clear_process_log = function() child.lua('_G.process_log = {}') end + +-- Data ======================================================================= +local test_items = { 'a_b_c', 'abc', 'a_b_b', 'c_a_a', 'b_c_c' } + +local many_items = {} +for i = 1, 1000000 do + many_items[3 * i - 2] = 'ab' + many_items[3 * i - 1] = 'ac' + many_items[3 * i] = 'bb' +end + +-- Output test set ============================================================ +local T = new_set({ + hooks = { + pre_case = function() + child.setup() + + -- Make more comfortable screenshots + child.set_size(15, 40) + child.o.laststatus = 0 + child.o.ruler = false + + load_module() + + -- Make border differentiable in screenshots + child.cmd('hi MiniPickBorder ctermfg=2') + end, + post_once = child.stop, + }, +}) + +-- Unit tests ================================================================= +T['setup()'] = new_set() + +T['setup()']['creates side effects'] = function() + -- Global variable + eq(child.lua_get('type(_G.MiniPick)'), 'table') + + -- Autocommand group + eq(child.fn.exists('#MiniPick'), 1) + + -- Highlight groups + local validate_hl_group = function(name, ref) expect.match(child.cmd_capture('hi ' .. name), ref) end + + -- - Make sure to clear highlight groups defined for better screenshots + child.cmd('hi clear MiniPickBorder') + load_module() + + validate_hl_group('MiniPickBorder', 'links to FloatBorder') + validate_hl_group('MiniPickBorderBusy', 'links to DiagnosticFloatingWarn') + validate_hl_group('MiniPickBorderText', 'links to FloatTitle') + validate_hl_group('MiniPickIconDirectory', 'links to Directory') + validate_hl_group('MiniPickIconFile', 'links to MiniPickNormal') + validate_hl_group('MiniPickHeader', 'links to DiagnosticFloatingHint') + validate_hl_group('MiniPickMatchCurrent', 'links to CursorLine') + validate_hl_group('MiniPickMatchMarked', 'links to Visual') + validate_hl_group('MiniPickMatchRanges', 'links to DiagnosticFloatingHint') + validate_hl_group('MiniPickNormal', 'links to NormalFloat') + validate_hl_group('MiniPickPreviewLine', 'links to CursorLine') + validate_hl_group('MiniPickPreviewRegion', 'links to IncSearch') + validate_hl_group('MiniPickPrompt', 'links to DiagnosticFloatingInfo') +end + +T['setup()']['creates `config` field'] = function() + eq(child.lua_get('type(_G.MiniPick.config)'), 'table') + + -- Check default values + local expect_config = function(field, value) eq(child.lua_get('MiniPick.config.' .. field), value) end + + expect_config('delay.async', 10) + expect_config('delay.busy', 50) + + expect_config('mappings.caret_left', '') + expect_config('mappings.caret_right', '') + expect_config('mappings.choose', '') + expect_config('mappings.choose_in_split', '') + expect_config('mappings.choose_in_tabpage', '') + expect_config('mappings.choose_in_vsplit', '') + expect_config('mappings.choose_marked', '') + expect_config('mappings.delete_char', '') + expect_config('mappings.delete_char_right', '') + expect_config('mappings.delete_left', '') + expect_config('mappings.delete_word', '') + expect_config('mappings.mark', '') + expect_config('mappings.mark_all', '') + expect_config('mappings.move_down', '') + expect_config('mappings.move_start', '') + expect_config('mappings.move_up', '') + expect_config('mappings.paste', '') + expect_config('mappings.refine', '') + expect_config('mappings.refine_marked', '') + expect_config('mappings.scroll_down', '') + expect_config('mappings.scroll_left', '') + expect_config('mappings.scroll_right', '') + expect_config('mappings.scroll_up', '') + expect_config('mappings.stop', '') + expect_config('mappings.toggle_info', '') + expect_config('mappings.toggle_preview', '') + + expect_config('options.content_from_bottom', false) + expect_config('options.use_cache', false) + + expect_config('source.items', vim.NIL) + expect_config('source.name', vim.NIL) + expect_config('source.cwd', vim.NIL) + expect_config('source.match', vim.NIL) + expect_config('source.show', vim.NIL) + expect_config('source.preview', vim.NIL) + expect_config('source.choose', vim.NIL) + expect_config('source.choose_marked', vim.NIL) + + expect_config('window.config', vim.NIL) +end + +T['setup()']['respects `config` argument'] = function() + unload_module() + load_module({ options = { use_cache = true } }) + eq(child.lua_get('MiniPick.config.options.use_cache'), true) +end + +T['setup()']['validates `config` argument'] = function() + unload_module() + + local expect_config_error = function(config, name, target_type) + expect.error(load_module, vim.pesc(name) .. '.*' .. vim.pesc(target_type), config) + end + + expect_config_error('a', 'config', 'table') + expect_config_error({ delay = 'a' }, 'delay', 'table') + expect_config_error({ delay = { async = 'a' } }, 'delay.async', 'number') + expect_config_error({ delay = { busy = 'a' } }, 'delay.busy', 'number') + + expect_config_error({ mappings = 'a' }, 'mappings', 'table') + expect_config_error({ mappings = { caret_left = 1 } }, 'mappings.caret_left', 'string') + expect_config_error({ mappings = { caret_right = 1 } }, 'mappings.caret_right', 'string') + expect_config_error({ mappings = { choose = 1 } }, 'mappings.choose', 'string') + expect_config_error({ mappings = { choose_in_split = 1 } }, 'mappings.choose_in_split', 'string') + expect_config_error({ mappings = { choose_in_tabpage = 1 } }, 'mappings.choose_in_tabpage', 'string') + expect_config_error({ mappings = { choose_in_vsplit = 1 } }, 'mappings.choose_in_vsplit', 'string') + expect_config_error({ mappings = { choose_marked = 1 } }, 'mappings.choose_marked', 'string') + expect_config_error({ mappings = { delete_char = 1 } }, 'mappings.delete_char', 'string') + expect_config_error({ mappings = { delete_char_right = 1 } }, 'mappings.delete_char_right', 'string') + expect_config_error({ mappings = { delete_left = 1 } }, 'mappings.delete_left', 'string') + expect_config_error({ mappings = { delete_word = 1 } }, 'mappings.delete_word', 'string') + expect_config_error({ mappings = { mark = 1 } }, 'mappings.mark', 'string') + expect_config_error({ mappings = { mark_all = 1 } }, 'mappings.mark_all', 'string') + expect_config_error({ mappings = { move_down = 1 } }, 'mappings.move_down', 'string') + expect_config_error({ mappings = { move_start = 1 } }, 'mappings.move_start', 'string') + expect_config_error({ mappings = { move_up = 1 } }, 'mappings.move_up', 'string') + expect_config_error({ mappings = { paste = 1 } }, 'mappings.paste', 'string') + expect_config_error({ mappings = { refine = 1 } }, 'mappings.refine', 'string') + expect_config_error({ mappings = { refine_marked = 1 } }, 'mappings.refine_marked', 'string') + expect_config_error({ mappings = { scroll_down = 1 } }, 'mappings.scroll_down', 'string') + expect_config_error({ mappings = { scroll_left = 1 } }, 'mappings.scroll_left', 'string') + expect_config_error({ mappings = { scroll_right = 1 } }, 'mappings.scroll_right', 'string') + expect_config_error({ mappings = { scroll_up = 1 } }, 'mappings.scroll_up', 'string') + expect_config_error({ mappings = { stop = 1 } }, 'mappings.stop', 'string') + expect_config_error({ mappings = { toggle_info = 1 } }, 'mappings.toggle_info', 'string') + expect_config_error({ mappings = { toggle_preview = 1 } }, 'mappings.toggle_preview', 'string') + + expect_config_error({ options = 'a' }, 'options', 'table') + expect_config_error({ options = { content_from_bottom = 1 } }, 'options.content_from_bottom', 'boolean') + expect_config_error({ options = { use_cache = 1 } }, 'options.use_cache', 'boolean') + + expect_config_error({ source = 'a' }, 'source', 'table') + expect_config_error({ source = { items = 1 } }, 'source.items', 'table') + expect_config_error({ source = { name = 1 } }, 'source.name', 'string') + expect_config_error({ source = { cwd = 1 } }, 'source.cwd', 'string') + expect_config_error({ source = { match = 1 } }, 'source.match', 'function') + expect_config_error({ source = { show = 1 } }, 'source.show', 'function') + expect_config_error({ source = { preview = 1 } }, 'source.preview', 'function') + expect_config_error({ source = { choose = 1 } }, 'source.choose', 'function') + expect_config_error({ source = { choose_marked = 1 } }, 'source.choose_marked', 'function') + + expect_config_error({ window = 'a' }, 'window', 'table') + expect_config_error({ window = { config = 1 } }, 'window.config', 'table or callable') +end + +-- This set mostly contains general function testing which doesn't fit into +-- more specialized integration tests later +T['start()'] = new_set() + +T['start()']['works'] = function() + child.lua_notify('_G.picked_item = MiniPick.start(...)', { { source = { items = test_items } } }) + child.expect_screenshot() + + -- Should focus on floating window + eq(child.api.nvim_get_current_win(), get_picker_state().windows.main) + + -- Should close window after an item and print it (as per `default_choose()`) + type_keys('') + child.expect_screenshot() + + -- Should return picked value + eq(child.lua_get('_G.picked_item'), test_items[1]) +end + +T['start()']['returns `nil` when there is no current match'] = function() + child.lua_notify('_G.picked_item = MiniPick.start(...)', { { source = { items = test_items } } }) + type_keys('x') + type_keys('') + eq(child.lua_get('_G.picked_item'), vim.NIL) +end + +T['start()']['works with window footer'] = function() + -- TODO: Use this as primary test after support for Neovim<=0.9 is dropped + if not child.has_float_footer() then return end + + child.lua_notify('_G.picked_item = MiniPick.start(...)', { { source = { items = test_items } } }) + child.expect_screenshot_orig() + + eq(child.api.nvim_get_current_win(), get_picker_state().windows.main) + type_keys('') + child.expect_screenshot_orig() + eq(child.lua_get('_G.picked_item'), test_items[1]) +end + +T['start()']['works on Neovim<0.9'] = function() + if child.fn.has('nvim-0.9') == 1 then return end + + child.lua_notify('_G.picked_item = MiniPick.start(...)', { { source = { items = test_items } } }) + child.expect_screenshot_orig() + + -- Should focus on floating window + eq(child.api.nvim_get_current_win(), get_picker_state().windows.main) + + -- Should close window after an item and print it (as per `default_choose()`) + type_keys('') + child.expect_screenshot_orig() + + -- Should return picked value + eq(child.lua_get('_G.picked_item'), test_items[1]) +end + +T['start()']['can be started without explicit items'] = function() + child.lua_notify('_G.picked_item = MiniPick.start()') + child.expect_screenshot() + type_keys('') + eq(child.lua_get('_G.picked_item'), vim.NIL) +end + +T['start()']['creates proper window'] = function() + start_with_items(test_items) + local win_id = get_picker_state().windows.main + eq(child.api.nvim_win_is_valid(win_id), true) + + local win_config = child.api.nvim_win_get_config(win_id) + eq(win_config.relative, 'editor') + eq(win_config.focusable, true) + + validate_win_option(win_id, 'list', true) + validate_win_option(win_id, 'listchars', 'extends:…') + validate_win_option(win_id, 'wrap', false) +end + +T['start()']['creates proper main buffer'] = function() + start_with_items(test_items) + local buf_id = get_picker_state().buffers.main + eq(child.api.nvim_buf_is_valid(buf_id), true) + validate_buf_option(buf_id, 'filetype', 'minipick') + validate_buf_option(buf_id, 'buflisted', false) + validate_buf_option(buf_id, 'buftype', 'nofile') +end + +T['start()']['tracks lost focus'] = function() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b' } }, + mappings = { error = { char = 'e', func = function() error() end } }, + })]]) + child.expect_screenshot() + type_keys('e') + -- By default it checks inside a timer with 1 second period + sleep(1000 + 50) + child.expect_screenshot() +end + +T['start()']['validates `opts`'] = function() + local validate = function(opts, error_pattern) + expect.error(function() child.lua('MiniPick.start(...)', { opts }) end, error_pattern) + end + + validate(1, 'Picker options.*table') + + validate({ delay = { async = 'a' } }, '`delay.async`.*number') + validate({ delay = { async = 0 } }, '`delay.async`.*positive') + validate({ delay = { busy = 'a' } }, '`delay.busy`.*number') + validate({ delay = { busy = 0 } }, '`delay.busy`.*positive') + + validate({ options = { content_from_bottom = 1 } }, '`options%.content_from_bottom`.*boolean') + validate({ options = { use_cache = 1 } }, '`options%.use_cache`.*boolean') + + validate({ mappings = { [1] = '' } }, '`mappings`.*only string fields') + validate({ mappings = { choose = 1 } }, 'Mapping for built%-in action "choose".*string') + expect.error( + function() child.lua('MiniPick.start({ mappings = { choose = { char = "a", func = function() end } } })') end, + 'built%-in action.*string' + ) + validate( + { mappings = { ['Custom action'] = 1 } }, + 'Mapping for custom action "Custom action".*table with `char` and `func`' + ) + + validate({ source = { items = 1 } }, '`source%.items`.*array or callable') + validate({ source = { cwd = 1 } }, '`source%.cwd`.*valid directory path') + validate({ source = { cwd = 'not-existing-path' } }, '`source%.cwd`.*valid directory path') + validate({ source = { match = 1 } }, '`source%.match`.*callable') + validate({ source = { show = 1 } }, '`source%.show`.*callable') + validate({ source = { preview = 1 } }, '`source%.preview`.*callable') + validate({ source = { choose = 1 } }, '`source%.choose`.*callable') + validate({ source = { choose_marked = 1 } }, '`source%.choose_marked`.*callable') + + validate({ window = { config = 1 } }, '`window%.config`.*table or callable') +end + +T['start()']['respects `source.items`'] = function() + -- Array + start_with_items({ 'a', 'b' }) + child.expect_screenshot() + stop() + + -- Callable returning array of items + child.lua([[_G.items_callable_return = function() return { 'c', 'd' } end]]) + child.lua_notify('MiniPick.start({ source = { items = _G.items_callable_return } })') + child.expect_screenshot() + stop() + + -- Callable setting items manually + child.lua([[_G.items_callable_later = function() MiniPick.set_picker_items({ 'e', 'f' }) end]]) + child.lua_notify('MiniPick.start({ source = { items = _G.items_callable_later } })') + poke_eventloop() + child.expect_screenshot() + stop() + + -- Callable setting items manually *later* + child.lua([[_G.items_callable_later = function() + vim.schedule(function() MiniPick.set_picker_items({ 'g', 'h' }) end) + end]]) + child.lua_notify('MiniPick.start({ source = { items = _G.items_callable_later } })') + poke_eventloop() + child.expect_screenshot() + stop() +end + +T['start()']['correctly computes stritems'] = function() + child.set_size(15, 80) + child.lua_notify([[MiniPick.start({ source = { items = { + 'string_item', + { text = 'table_item' }, + { a = 'fallback item', b = 1 }, + function() return 'string_item_from_callable' end, + function() return { text = 'table_item_from_callable' } end, + function() return { c = 'fallback item from callable', d = 1 } end, + } } })]]) + child.expect_screenshot() +end + +T['start()']['resolves items after making picker active'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = function() + _G.picker_is_active = MiniPick.is_picker_active() + _G.picker_name = MiniPick.get_picker_opts().source.name + return { 'a', 'b' } + end, + name = 'This picker' + } })]]) + eq(get_picker_stritems(), { 'a', 'b' }) + eq(child.lua_get('_G.picker_is_active'), true) + eq(child.lua_get('_G.picker_name'), 'This picker') +end + +T['start()']['respects `source.name`'] = function() + start({ source = { items = test_items, name = 'Hello' } }) + validate_picker_option('source.name', 'Hello') + if child.has_float_footer() then child.expect_screenshot_orig() end +end + +T['start()']['respects `source.cwd`'] = function() + local lua_cmd = string.format( + [[MiniPick.start({ source = { + items = function() return { MiniPick.get_picker_opts().source.cwd } end, + cwd = %s, + } })]], + vim.inspect(test_dir) + ) + child.lua_notify(lua_cmd) + local actual_cwd = get_picker_stritems()[1] + eq(actual_cwd, full_path(test_dir)) + eq(actual_cwd:find('/$'), nil) +end + +T['start()']['respects `source.match`'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', 'b', 'c' }, + match = function(...) + _G.match_args = { ... } + return { 2 } + end, + } })]]) + + child.expect_screenshot() + eq(get_picker_matches().all, { 'b' }) + eq(child.lua_get('_G.match_args'), { { 'a', 'b', 'c' }, { 1, 2, 3 }, {} }) + + type_keys('x') + eq(get_picker_matches().all, { 'b' }) + eq(child.lua_get('_G.match_args'), { { 'a', 'b', 'c' }, { 2 }, { 'x' } }) +end + +T['start()']['respects `source.show`'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', { text = 'b' }, 'bb' }, + show = function(buf_id, items_to_show, query, ...) + _G.show_args = { buf_id, items_to_show, query, ... } + local lines = vim.tbl_map( + function(x) return '__' .. (type(x) == 'table' and x.text or x) end, + items_to_show + ) + vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) + end, + } })]]) + local buf_id = get_picker_state().buffers.main + + child.expect_screenshot() + eq(child.lua_get('_G.show_args'), { buf_id, { 'a', { text = 'b' }, 'bb' }, {} }) + + type_keys('b') + child.expect_screenshot() + eq(child.lua_get('_G.show_args'), { buf_id, { { text = 'b' }, 'bb' }, { 'b' } }) +end + +T['start()']['respects `source.preview`'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', { text = 'b' }, 'bb' }, + preview = function(buf_id, item, ...) + _G.preview_args = { buf_id, item, ... } + local stritem = type(item) == 'table' and item.text or item + vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, { 'Preview: ' .. stritem }) + end, + } })]]) + local validate_preview_args = function(item_ref) + local preview_args = child.lua_get('_G.preview_args') + eq(child.api.nvim_buf_is_valid(preview_args[1]), true) + eq(preview_args[2], item_ref) + end + + type_keys('') + + child.expect_screenshot() + validate_preview_args('a') + local preview_buf_id_1 = child.lua_get('_G.preview_args')[1] + + type_keys('') + child.expect_screenshot() + validate_preview_args({ text = 'b' }) + eq(preview_buf_id_1 ~= child.lua_get('_G.preview_args')[1], true) +end + +T['start()']['respects `source.choose`'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', { text = 'b' }, 'bb' }, + choose = function(...) _G.choose_args = { ... } end, + } })]]) + + type_keys('', '') + eq(child.lua_get('_G.choose_args'), { { text = 'b' } }) + eq(is_picker_active(), false) +end + +T['start()']['respects `source.choose_marked`'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', { text = 'b' }, 'bb' }, + choose_marked = function(...) _G.choose_marked_args = { ... } end, + } })]]) + + type_keys('', '', '', '') + eq(child.lua_get('_G.choose_marked_args'), { { 'a', { text = 'b' } } }) + eq(is_picker_active(), false) +end + +T['start()']['respects `delay.async`'] = function() + child.set_size(15, 15) + child.lua_notify([[ + _G.buf_id, _G.n = vim.api.nvim_get_current_buf(), 0 + local timer = vim.loop.new_timer() + local f = vim.schedule_wrap(function() + _G.n = _G.n + 1 + vim.fn.appendbufline(_G.buf_id, '$', { 'Line ' .. _G.n }) + end) + timer:start(50, 50, f) + ]]) + local validate = function(n, lines) + eq(child.lua_get('_G.n'), n) + eq(child.lua_get('vim.api.nvim_buf_get_lines(_G.buf_id, 0, -1, false)'), lines) + child.expect_screenshot() + end + + child.lua_notify([[MiniPick.start({ source = { items = { 'a' } }, delay = { async = 80 } })]]) + validate(0, { '' }) + + -- Callback should have already been executed, but not redraw + sleep(50 + 5) + validate(1, { '', 'Line 1' }) + + -- No new callback should have been executed, but redraw should + sleep(30) + validate(1, { '', 'Line 1' }) + + -- Test that redraw is done repeatedly + sleep(80) + validate(3, { '', 'Line 1', 'Line 2', 'Line 3' }) +end + +T['start()']['respects `delay.busy`'] = function() + local validate = function(is_busy) + local win_id = get_picker_state().windows.main + local ref_winhl = 'FloatBorder:MiniPickBorder' .. (is_busy and 'Busy' or '') + expect.match(child.api.nvim_win_get_option(win_id, 'winhighlight'), ref_winhl) + end + + local new_busy_delay = math.floor(0.5 * child.lua_get('MiniPick.config.delay.busy')) + child.lua_notify(string.format('MiniPick.start({ delay = { busy = %d } })', new_busy_delay)) + + validate(false) + sleep(new_busy_delay + 10) + validate(true) +end + +T['start()']['respects `mappings`'] = function() + start({ source = { items = { 'a', 'b' } }, mappings = { stop = 'c' } }) + eq(is_picker_active(), true) + type_keys('a') + eq(is_picker_active(), true) + type_keys('c') + eq(is_picker_active(), false) +end + +T['start()']['respects `options.content_from_bottom`'] = function() + start({ source = { items = { 'a', 'b' } }, options = { content_from_bottom = true } }) + child.expect_screenshot() +end + +T['start()']['respects `options.use_cache`'] = function() + local validate_match_calls = make_match_with_count() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'bb' }, match = _G.match_with_count }, + options = { use_cache = true }, + })]]) + validate_match_calls(0, { 1, 2, 3 }) + + type_keys('b') + validate_match_calls(1, { 2, 3 }) + + type_keys('b') + validate_match_calls(2, { 3 }) + + type_keys('') + validate_match_calls(2, { 2, 3 }) + + type_keys('') + validate_match_calls(2, { 1, 2, 3 }) + + type_keys('b') + validate_match_calls(2, { 2, 3 }) + + type_keys('x') + validate_match_calls(3, {}) +end + +T['start()']['allows custom mappings'] = function() + -- Both in global and local config + child.lua([[MiniPick.config.mappings.custom_global = { + char = '', + func = function(...) _G.args_global = { ... } end, + }]]) + + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b' } }, + mappings = { + -- Return value is treated as "should stop picker after execution" + custom = { char = 'm', func = function(...) _G.args_local = { ... }; return true end }, + }, + })]]) + + type_keys('') + eq(child.lua_get('_G.args_global'), {}) + eq(is_picker_active(), true) + + type_keys('m') + eq(child.lua_get('_G.args_local'), {}) + eq(is_picker_active(), false) +end + +T['start()']['allows overriding built-in mappings'] = function() + -- Both in global/local config **but** only as strings + child.lua([[MiniPick.config.mappings.caret_left = '']]) + + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b' } }, + mappings = { caret_right = 'm' }, + })]]) + + type_keys('a') + eq(get_picker_state().caret, 2) + type_keys('') + eq(get_picker_state().caret, 1) + type_keys('m') + eq(get_picker_state().caret, 2) +end + +T['start()']['respects `window.config`'] = function() + -- As table + start({ source = { items = { 'a', 'b', 'c' } }, window = { config = { border = 'double' } } }) + child.expect_screenshot() + stop() + + -- As callable + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'c' } }, + window = { config = function() return { anchor = 'NW', row = 2, width = vim.o.columns } end }, + })]]) + child.expect_screenshot() + stop() +end + +T['start()']['stops currently active picker'] = function() + start_with_items({ 'a', 'b', 'c' }) + eq(is_picker_active(), true) + start_with_items({ 'd', 'e', 'f' }) + sleep(2) + child.expect_screenshot() +end + +T['start()']['stops impoperly aborted previous picker'] = function() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'c' } }, + mappings = { error = { char = 'e', func = function() error() end } }, + })]]) + child.expect_screenshot() + type_keys('e') + + start({ source = { items = { 'd', 'e', 'f' } }, window = { config = { width = 10 } } }) + child.expect_screenshot() +end + +T['start()']['triggers `MiniPickStart` User event'] = function() + make_event_log() + child.cmd('au User MiniPickStart lua _G.track_event()') + start_with_items(test_items) + + -- User event should be triggered when all elements are usually set + eq(child.lua_get('_G.event_log'), { #test_items }) +end + +T['start()']['respects global config'] = function() + child.lua([[MiniPick.config.window.config = { anchor = 'NW', row = 1 }]]) + start_with_items({ 'a', 'b', 'c' }) + child.expect_screenshot() +end + +T['start()']['respects `vim.b.minipick_config`'] = function() + child.lua([[MiniPick.config.window.config = { anchor = 'NW', row = 1 }]]) + child.b.minipick_config = { window = { config = { row = 3, width = 10 } } } + start_with_items({ 'a', 'b', 'c' }) + child.expect_screenshot() +end + +T['stop()'] = new_set() + +T['stop()']['works'] = function() + start_with_items(test_items) + child.expect_screenshot() + stop() + child.expect_screenshot() + eq(is_picker_active(), false) +end + +T['stop()']['can be called without active picker'] = function() expect.no_error(stop) end + +T['stop()']['triggers `MiniPickStop` User event'] = function() + make_event_log() + child.cmd('au User MiniPickStop lua _G.track_event()') + start_with_items(test_items) + stop() + -- User event should be triggered while buffer is still valid + eq(child.lua_get('_G.event_log'), { #test_items }) +end + +T['refresh()'] = new_set() + +local refresh = forward_lua('MiniPick.refresh') + +T['refresh()']['works'] = function() + start_with_items(test_items) + child.expect_screenshot() + + child.lua('MiniPick.set_picker_opts({ window = { config = { width = 10 } } })') + refresh() + child.expect_screenshot() +end + +T['refresh()']['is called on `VimResized`'] = function() + child.set_size(15, 40) + start_with_items(test_items) + child.expect_screenshot() + + child.set_size(15, 20) + child.expect_screenshot() +end + +T['refresh()']['can be called without active picker'] = function() expect.no_error(refresh) end + +T['refresh()']['recomputes window config'] = function() + child.lua([[ + _G.width = 0 + _G.win_config = function() + _G.width = _G.width + 10 + return { width = _G.width } + end + ]]) + + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'b', 'c' } }, window = { config = _G.win_config } })]]) + child.expect_screenshot() + refresh() + child.expect_screenshot() +end + +T['default_match()'] = new_set() + +local default_match = forward_lua('MiniPick.default_match') + +local validate_match = + function(stritems, query, output_ref) eq(default_match(stritems, seq_along(stritems), query), output_ref) end + +T['default_match()']['works with active picker'] = function() + start_with_items(test_items) + type_keys('a') + child.expect_screenshot() + type_keys('b') + child.expect_screenshot() +end + +T['default_match()']['does not block query update'] = function() + child.lua([[ + _G.log = {} + _G.default_match_wrapper = function(stritems, inds, query) + table.insert(_G.log, { n_match_inds = #inds, query = vim.deepcopy(query) }) + MiniPick.default_match(stritems, inds, query) + end + ]]) + child.lua_notify('MiniPick.start({ source = { match = _G.default_match_wrapper }, delay = { async = 1 } })') + + -- Set many items and wait until it completely sets + set_picker_items(many_items) + for i = 1, 50 do + sleep(100) + if child.lua_get([[type(MiniPick.get_picker_items()) == 'table']]) then break end + end + + -- Type three characters very quickly. If `default_match()` were blocking, + -- each press would lead to calling `source.match` with the result of + -- matching on prior query. In this test every key press should interrupt + -- currently active matching and start a new one with the latest available + -- set of `match_inds` (which should be all inds as match is, hopefully, + -- never finishes). + type_keys('a') + sleep(1) + type_keys('b') + sleep(1) + type_keys('c') + sleep(1) + child.expect_screenshot() + eq(child.lua_get('_G.log'), { + { n_match_inds = #many_items, query = {} }, + { n_match_inds = #many_items, query = { 'a' } }, + { n_match_inds = #many_items, query = { 'a', 'b' } }, + { n_match_inds = #many_items, query = { 'a', 'b', 'c' } }, + }) +end + +T['default_match()']['works without active picker'] = function() + local stritems, query = { 'aab', 'ac', 'ab' }, { 'a', 'b' } + eq(default_match(stritems, { 1, 2, 3 }, query), { 3, 1 }) + eq(default_match(stritems, { 2, 3 }, query), { 3 }) +end + +T['default_match()']['works with empty inputs'] = function() + local match_inds, stritems, query = seq_along(test_items), { 'ab', 'cd' }, { 'a' } + eq(default_match(stritems, {}, query), {}) + eq(default_match({}, {}, query), {}) + eq(default_match(stritems, match_inds, {}), seq_along(stritems)) +end + +T['default_match()']['filters items that match query with gaps'] = function() + -- Regular cases + validate_match({ 'a__', 'b' }, { 'a' }, { 1 }) + validate_match({ '_a_', 'b' }, { 'a' }, { 1 }) + validate_match({ '__a', 'b' }, { 'a' }, { 1 }) + validate_match({ 'b', 'a__' }, { 'a' }, { 2 }) + validate_match({ 'b', '_a_' }, { 'a' }, { 2 }) + validate_match({ 'b', '__a' }, { 'a' }, { 2 }) + + validate_match({ 'a', 'ab', 'a_b', 'a_b_b', 'ba' }, { 'a', 'b' }, { 2, 3, 4 }) + validate_match({ 'a', 'ab', 'a_b', 'a_b_b', 'ba' }, { 'a', 'b', 'b' }, { 4 }) + + validate_match({ 'a', 'ab', 'axb', 'a?b', 'a\tb' }, { 'a', 'b' }, { 2, 3, 4, 5 }) + + -- Non-single-char-entries queries (each should match exactly) + validate_match({ 'a', 'b', 'ab_', 'a_b', '_ab' }, { 'ab' }, { 3, 5 }) + validate_match({ 'abcd_', '_abcd', 'a_bcd', 'ab_cd', 'abc_d' }, { 'ab', 'cd' }, { 1, 2, 4 }) + + -- Edge casees + validate_match({ 'a', 'b', '' }, { 'a' }, { 1 }) + + validate_match({ 'a', 'b', '' }, { '' }, { 1, 2, 3 }) + validate_match({ 'a', 'b', '' }, { '', '' }, { 1, 2, 3 }) +end + +T['default_match()']['sorts by match width -> match start -> item index'] = function() + local query_ab, query_abc = { 'a', 'b' }, { 'a', 'b', 'c' } + + -- Width differs + validate_match({ 'ab', 'a_b', 'a__b' }, query_ab, { 1, 2, 3 }) + validate_match({ 'ab', 'a__b', 'a_b' }, query_ab, { 1, 3, 2 }) + validate_match({ 'a__b', 'ab', 'a_b' }, query_ab, { 2, 3, 1 }) + validate_match({ 'a_b', 'ab', 'a__b' }, query_ab, { 2, 1, 3 }) + validate_match({ 'a_b', 'a__b', 'ab' }, query_ab, { 3, 1, 2 }) + validate_match({ 'a__b', 'a_b', 'ab' }, query_ab, { 3, 2, 1 }) + + validate_match({ '_a__b', '_a_b', '_ab' }, query_ab, { 3, 2, 1 }) + + validate_match({ 'a__b_a___b', 'a_b_a___b', 'ab_a___b' }, query_ab, { 3, 2, 1 }) + + validate_match({ 'a_b_c', 'a_bc', 'abc' }, query_abc, { 3, 2, 1 }) + validate_match({ '_a_b_c', '_a_bc', '_abc' }, query_abc, { 3, 2, 1 }) + validate_match({ 'a_b_c_a__b__c', 'a_bc_a__b__c', 'abc_a__b__c' }, query_abc, { 3, 2, 1 }) + + validate_match({ 'ab__cd', 'ab_cd', 'abcd' }, { 'ab', 'cd' }, { 3, 2, 1 }) + + -- Start differs with equal width + validate_match({ 'ab', '_ab', '__ab' }, query_ab, { 1, 2, 3 }) + validate_match({ 'ab', '__ab', '_ab' }, query_ab, { 1, 3, 2 }) + validate_match({ '_ab', 'ab', '__ab' }, query_ab, { 2, 1, 3 }) + validate_match({ '__ab', 'ab', '_ab' }, query_ab, { 2, 3, 1 }) + validate_match({ '_ab', '__ab', 'ab' }, query_ab, { 3, 1, 2 }) + validate_match({ '__ab', '_ab', 'ab' }, query_ab, { 3, 2, 1 }) + + validate_match({ '__abc', '_abc', 'abc' }, query_abc, { 3, 2, 1 }) + + validate_match({ '__abc_a_b_c', '_abc_a_b_c', 'abc_a_b_c' }, query_abc, { 3, 2, 1 }) + validate_match({ 'a_b_c__abc', 'a_b_c_abc', 'a_b_cabc' }, query_abc, { 3, 2, 1 }) + + validate_match({ '__a_b_c', '_a__bc', 'ab__c' }, query_abc, { 3, 2, 1 }) + + validate_match({ '__ab_cd_e', '_ab__cde', 'abcd__e' }, { 'ab', 'cd', 'e' }, { 3, 2, 1 }) + + -- Index differs with equal width and start + validate_match({ 'a_b_c', 'a__bc', 'ab__c' }, query_abc, { 1, 2, 3 }) + validate_match({ 'axbxc', 'a??bc', 'ab\t\tc' }, query_abc, { 1, 2, 3 }) + + validate_match({ 'ab_cd_e', 'ab__cde', 'abcd__e' }, { 'ab', 'cd', 'e' }, { 1, 2, 3 }) +end + +T['default_match()']['filters and sorts'] = function() + validate_match({ 'a_b_c', 'abc', 'a_b_b', 'c_a_a', 'b_c_c' }, { 'a', 'b' }, { 2, 1, 3 }) + validate_match({ 'xabcd', 'axbcd', 'abxcd', 'abcxd', 'abcdx' }, { 'ab', 'cd' }, { 5, 1, 3 }) +end + +T['default_match()']['respects special queries'] = function() + --stylua: ignore + local stritems = { + '*abc', -- 1 + '_*_a_bc', -- 2 + "'abc", -- 3 + "_'_a_bc", -- 4 + '^abc', -- 5 + '_^_a_bc', -- 6 + 'abc$', -- 7 + 'ab_c_$_', -- 8 + 'a b c', -- 9 + ' a bc', -- 10 + } + local all_inds = seq_along(stritems) + local validate = function(query, output_ref) validate_match(stritems, query, output_ref) end + local validate_same_as = function(query, query_ref) + eq(default_match(stritems, all_inds, query), default_match(stritems, all_inds, query_ref)) + end + + -- Precedence: + -- "forced fuzzy" = "forced exact" > "exact start/end" > "grouped fuzzy" + + -- Forced fuzzy + validate_same_as({ '*' }, { '' }) + validate_same_as({ '*', 'a' }, { 'a' }) + validate_same_as({ '*', 'a', 'b' }, { 'a', 'b' }) + + validate({ '*', '*', 'a' }, { 1, 2 }) + validate({ '*', "'", 'a' }, { 3, 4 }) + validate({ '*', '^', 'a' }, { 5, 6 }) + validate({ '*', 'a', '$' }, { 7, 8 }) + validate({ '*', 'a', ' ', 'b' }, { 9, 10 }) + + -- Forced exact + validate_same_as({ "'" }, { '' }) + validate_same_as({ "'", 'a' }, { 'a' }) + validate_same_as({ "'", 'a', 'b' }, { 'ab' }) + + validate({ "'", '*', 'a' }, { 1 }) + validate({ "'", "'", 'a' }, { 3 }) + validate({ "'", '^', 'a' }, { 5 }) + validate({ "'", 'c', '$' }, { 7 }) + validate({ "'", 'a', ' ', 'b' }, { 9 }) + + -- Exact start + validate_same_as({ '^' }, { '' }) + validate({ '^', 'a' }, { 7, 8, 9 }) + validate({ '^', 'a', 'b' }, { 7, 8 }) + + validate({ '^', '^', 'a' }, { 5 }) + validate({ '^', "'", 'a' }, { 3 }) + validate({ '^', '*', 'a' }, { 1 }) + validate({ '^', ' ', 'a' }, { 10 }) + + -- Exact end + validate({ '$' }, all_inds) + validate({ 'c', '$' }, { 1, 3, 5, 9, 10, 2, 4, 6 }) + validate({ 'b', 'c', '$' }, { 1, 3, 5, 10, 2, 4, 6 }) + + validate({ ' ', 'c', '$' }, { 9 }) + + -- Grouped + validate_same_as({ 'a', ' ' }, { 'a' }) + validate_same_as({ 'a', ' ', ' ' }, { 'a' }) + validate_same_as({ 'a', ' ', 'b' }, { 'a', 'b' }) + validate_same_as({ 'a', ' ', ' ', 'b' }, { 'a', 'b' }) + validate_same_as({ 'a', ' ', 'b', ' ' }, { 'a', 'b' }) + validate_same_as({ 'a', ' ', 'b', ' ', 'c' }, { 'a', 'b', 'c' }) + validate_same_as({ 'a', ' ', 'b', ' ', ' ', 'c' }, { 'a', 'b', 'c' }) + validate_same_as({ 'a', ' ', 'b', ' ', 'c', ' ' }, { 'a', 'b', 'c' }) + + validate({ 'a', 'b', ' ', 'c' }, { 7, 1, 3, 5, 8 }) + validate({ 'a', ' ', 'b', 'c' }, { 7, 1, 3, 5, 2, 4, 6, 10 }) + validate({ 'a', 'b', 'c', ' ' }, { 7, 1, 3, 5 }) + + validate({ 'ab', ' ', 'c' }, { 7, 1, 3, 5, 8 }) + + -- - Whitespace inside non-whitespace elements shouldn't matter + validate({ 'a b', ' ', 'c' }, { 9 }) + + -- - Amount and type of whitespace inside "split" elements shouldn't matter + validate_same_as({ 'ab', ' ', 'c' }, { 'ab', ' ', 'c' }) + validate_same_as({ 'ab', '\t', 'c' }, { 'ab', ' ', 'c' }) + + -- - Only whitespace is allowed + validate_same_as({ ' ' }, { '' }) + validate_same_as({ ' ', ' ' }, { '' }) + + -- Combination + validate_same_as({ '^', '$' }, { '' }) + validate({ '^', 'a', ' ', 'b', ' ', 'c', '$' }, { 9 }) + + -- Not special + validate({ 'a', '*' }, {}) + validate({ 'a', "'" }, {}) + validate({ 'a', '^' }, {}) + validate({ '$', 'a' }, {}) +end + +T['default_match()']['only input indexes can be in the output'] = function() + eq(default_match({ 'a', '_a', '__a', 'b' }, { 1, 2, 4 }, { 'a' }), { 1, 2 }) + + -- Special modes + eq(default_match({ 'a', '_a', '__a', 'b' }, { 1, 2, 4 }, { "'", 'a' }), { 1, 2 }) + eq(default_match({ 'a', '_a', '__a', 'b' }, { 1, 2, 4 }, { '*', 'a' }), { 1, 2 }) + eq(default_match({ 'a', 'a_', 'a__', 'b' }, { 1, 2, 4 }, { '^', 'a' }), { 1, 2 }) + eq(default_match({ 'a', '_a', '__a', 'b' }, { 1, 2, 4 }, { 'a', '$' }), { 1, 2 }) + + eq(default_match({ 'abc', 'ab_c', 'ab__c', 'a_b_c' }, { 1, 2, 4 }, { 'a', 'b', ' ', 'c' }), { 1, 2 }) +end + +T['default_match()']['works with multibyte characters'] = function() + -- In query + validate_match({ 'ы', 'ф', 'd' }, { 'ы' }, { 1 }) + + validate_match({ 'ы__ф', 'ы_ф', 'ыф', 'ы', 'фы' }, { 'ы', 'ф' }, { 3, 2, 1 }) + validate_match({ '__ыф', '_ыф', 'ыф' }, { 'ы', 'ф' }, { 3, 2, 1 }) + validate_match({ '__ы_ф_я', '__ы__фя', '__ыф__я' }, { 'ы', 'ф', 'я' }, { 1, 2, 3 }) + + validate_match({ 'ы_ф', '_ыф', 'ы' }, { '*', 'ы', 'ф' }, { 2, 1 }) + validate_match({ 'ы_ф', '_ыф', 'ы' }, { "'", 'ы', 'ф' }, { 2 }) + validate_match({ 'ы_ф', '_ыф', 'ы' }, { '^', 'ы' }, { 1, 3 }) + validate_match({ 'ы_ф', '_ыф', 'ы' }, { 'ф', '$' }, { 1, 2 }) + validate_match({ 'ыы_ф', 'ы_ыф' }, { 'ы', 'ы', ' ', 'ф' }, { 1 }) + + validate_match({ '_│_│', '│_│_', '_│_' }, { '│', '│' }, { 2, 1 }) + + validate_match({ 'ыdф', '_ы_d_ф' }, { 'ы', 'd', 'ф' }, { 1, 2 }) + + -- In stritems + validate_match({ 'aыbыc', 'abыc' }, { 'a', 'b', 'c' }, { 2, 1 }) +end + +T['default_match()']['works with special characters'] = function() + -- function() validate_match('(.+*%-)', 'a(a.a+a*a%a-a)', { 2, 4, 6, 8, 10, 12, 14 }) end + local validate_match_special_char = function(char) + local stritems = { 'a' .. char .. 'b', 'a_b' } + validate_match(stritems, { char }, { 1 }) + validate_match(stritems, { 'a', char, 'b' }, { 1 }) + end + + validate_match_special_char('.') + validate_match_special_char('+') + validate_match_special_char('%') + validate_match_special_char('-') + validate_match_special_char('(') + validate_match_special_char(')') + + validate_match({ 'a*b', 'a_b' }, { 'a', '*', 'b' }, { 1 }) + validate_match({ 'a^b', 'a_b' }, { 'a', '^', 'b' }, { 1 }) + validate_match({ 'a$b', 'a_b' }, { 'a', '$', 'b' }, { 1 }) +end + +T['default_match()']['respects case'] = function() + -- Ignore and smart case should come from how picker uses `source.match` + validate_match({ 'ab', 'aB', 'Ba', 'AB' }, { 'a', 'b' }, { 1 }) + validate_match({ 'ab', 'aB', 'Ba', 'AB' }, { 'a', 'B' }, { 2 }) +end + +T['default_show()'] = new_set({ hooks = { pre_case = function() child.set_size(10, 20) end } }) + +local default_show = forward_lua('MiniPick.default_show') + +T['default_show()']['works'] = function() + child.set_size(15, 40) + start_with_items({ 'abc', 'a_bc', 'a__bc' }) + type_keys('a', 'b') + child.expect_screenshot() +end + +T['default_show()']['works without active picker'] = function() + -- Allows 0 buffer id for current buffer + default_show(0, { 'abc', 'a_bc', 'a__bc' }, { 'a', 'b' }) + child.expect_screenshot() + + -- Allows non-current buffer + local new_buf_id = child.api.nvim_create_buf(false, true) + default_show(new_buf_id, { 'def', 'd_ef', 'd__ef' }, { 'd', 'e' }) + child.api.nvim_set_current_buf(new_buf_id) + child.expect_screenshot() +end + +T['default_show()']['shows best match'] = function() + default_show(0, { 'a__b_a__b_ab', 'a__b_ab_a__b', 'ab_a__b_a__b', 'ab__ab' }, { 'a', 'b' }) + child.expect_screenshot() + + default_show(0, { 'aabbccddee' }, { 'a', 'b', 'c', 'd', 'e' }) + child.expect_screenshot() +end + +T['default_show()']['respects `opts.show_icons`'] = function() + child.set_size(10, 45) + local items = vim.tbl_map(real_file, vim.fn.readdir(real_files_dir)) + table.insert(items, test_dir) + table.insert(items, 'non-existing') + table.insert(items, { text = 'non-string' }) + local query = { 'i', 'i' } + + -- Without 'nvim-web-devicons' + default_show(0, items, query, { show_icons = true }) + child.expect_screenshot() + + -- With 'nvim-web-devicons' + child.cmd('set rtp+=tests/dir-pick') + default_show(0, items, query, { show_icons = true }) + child.expect_screenshot() +end + +T['default_show()']['handles stritems with non-trivial whitespace'] = function() + child.o.tabstop = 3 + default_show(0, { 'With\nnewline', 'With\ttab' }, {}) + child.expect_screenshot() +end + +T['default_show()']["respects 'ignorecase'/'smartcase'"] = function() + child.set_size(7, 12) + local items = { 'a_b', 'a_B', 'A_b', 'A_B' } + + local validate = function() + default_show(0, items, { 'a', 'b' }) + child.expect_screenshot() + default_show(0, items, { 'a', 'B' }) + child.expect_screenshot() + end + + -- Respect case + child.o.ignorecase, child.o.smartcase = false, false + validate() + + -- Ignore case + child.o.ignorecase, child.o.smartcase = true, false + validate() + + -- Smart case + child.o.ignorecase, child.o.smartcase = true, true + validate() +end + +T['default_show()']['handles query similar to `default_match`'] = function() + child.set_size(15, 15) + local items = { 'abc', '_abc', 'a_bc', 'ab_c', 'abc_', '*abc', "'abc", '^abc', 'abc$', 'a b c' } + + local validate = function(query) + default_show(0, items, query) + child.expect_screenshot() + end + + validate({ '*', 'a', 'b' }) + validate({ "'", 'a', 'b' }) + validate({ '^', 'a', 'b' }) + validate({ 'b', 'c', '$' }) + validate({ 'a', 'b', ' ', 'c' }) +end + +T['default_show()']['works with multibyte characters'] = function() + local items = { 'ыdф', 'ыы_d_ф', '_ыы_d_ф' } + + -- In query + default_show(0, items, { 'ы', 'ф' }) + child.expect_screenshot() + + -- Not in query + default_show(0, items, { 'd' }) + child.expect_screenshot() +end + +T['default_show()']['works with non-single-char-entries queries'] = function() + local items = { '_abc', 'a_bc', 'ab_c', 'abc_' } + local validate = function(query) + default_show(0, items, query) + child.expect_screenshot() + end + + validate({ 'ab', 'c' }) + validate({ 'abc' }) + validate({ 'a b', ' ', 'c' }) +end + +T['default_preview()'] = new_set() + +local default_preview = forward_lua('MiniPick.default_preview') + +local validate_preview = function(items) + start_with_items(items) + type_keys('') + child.expect_screenshot() + + for _ = 1, (#items - 1) do + type_keys('') + child.expect_screenshot() + end +end + +T['default_preview()']['works'] = function() validate_preview({ real_file('b.txt') }) end + +T['default_preview()']['works without active picker'] = function() + -- Allows 0 buffer id for current buffer + default_preview(0, real_file('b.txt')) + child.expect_screenshot() + + -- Allows non-current buffer + local new_buf_id = child.api.nvim_create_buf(false, true) + default_preview(new_buf_id, real_file('LICENSE')) + child.api.nvim_set_current_buf(new_buf_id) + child.expect_screenshot() +end + +T['default_preview()']['works for file path'] = function() + local items = { + -- Item as string + real_file('b.txt'), + + -- Item as table with `path` field + { text = real_file('LICENSE'), path = real_file('LICENSE') }, + + -- Non-text file + real_file('c.gif'), + } + validate_preview(items) +end + +T['default_preview()']['shows line in file path'] = function() + local path = real_file('b.txt') + local items = { + path .. ':3', + { text = path .. ':line-in-path', path = path .. ':6' }, + { text = path .. ':line-separate', path = path, lnum = 8 }, + } + validate_preview(items) +end + +T['default_preview()']['shows position in file path'] = function() + local path = real_file('b.txt') + local items = { + path .. ':3:4', + { text = path .. ':pos-in-path', path = path .. ':6:2' }, + { text = path .. ':pos-separate', path = path, lnum = 8, col = 3 }, + } + validate_preview(items) +end + +T['default_preview()']['shows region in file path'] = function() + local path = real_file('b.txt') + local items = { + { text = path .. ':region-oneline', path = path, lnum = 8, col = 3, end_lnum = 8, end_col = 5 }, + { text = path .. ':region-manylines', path = path, lnum = 9, col = 3, end_lnum = 11, end_col = 4 }, + } + validate_preview(items) +end + +T['default_preview()']['has syntax highlighting in file path'] = function() + local items = { + -- With tree-sitter + real_file('a.lua'), + + -- With built-in syntax + real_file('Makefile'), + } + validate_preview(items) +end + +T['default_preview()']['loads context in file path'] = function() + start_with_items({ real_file('b.txt') }) + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() +end + +T['default_preview()']['works for directory path'] = + function() validate_preview({ test_dir, { text = real_files_dir, path = real_files_dir } }) end + +T['default_preview()']['works for buffer'] = function() + local buf_id_1 = child.api.nvim_create_buf(false, false) + local buf_id_2 = child.api.nvim_create_buf(true, false) + local buf_id_3 = child.api.nvim_create_buf(false, true) + local buf_id_4 = child.api.nvim_create_buf(true, true) + + child.api.nvim_buf_set_lines(buf_id_1, 0, -1, false, { 'This is buffer #1' }) + child.api.nvim_buf_set_lines(buf_id_2, 0, -1, false, { 'This is buffer #2' }) + child.api.nvim_buf_set_lines(buf_id_3, 0, -1, false, { 'This is buffer #3' }) + child.api.nvim_buf_set_lines(buf_id_4, 0, -1, false, { 'This is buffer #4' }) + + local items = { + -- As number + buf_id_1, + + -- As string convertible to number + tostring(buf_id_1), + + -- As table with `bufnr` field + { text = 'Buffer #2', bufnr = buf_id_2 }, + + -- As table with `buf_id` field + { text = 'Buffer #3', buf_id = buf_id_3 }, + + -- As table with `buf` field + { text = 'Buffer #4', buf = buf_id_4 }, + } + validate_preview(items) +end + +local mock_buffer_for_preview = function() + local buf_id = child.api.nvim_create_buf(true, false) + local lines = {} + for i = 1, 20 do + table.insert(lines, string.format('Line %d in buffer %d', i, buf_id)) + end + child.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) + return buf_id +end + +T['default_preview()']['shows line in buffer'] = function() + local buf_id = mock_buffer_for_preview() + validate_preview({ { text = 'Line in buffer', bufnr = buf_id, lnum = 4 } }) +end + +T['default_preview()']['shows position in buffer'] = function() + local buf_id = mock_buffer_for_preview() + validate_preview({ { text = 'Position in buffer', bufnr = buf_id, lnum = 6, col = 3 } }) +end + +T['default_preview()']['shows region in buffer'] = function() + local buf_id = mock_buffer_for_preview() + local items = { + { text = 'Oneline region in buffer', bufnr = buf_id, lnum = 8, col = 3, end_lnum = 8, end_col = 6 }, + { text = 'Manylines region in buffer', bufnr = buf_id, lnum = 10, col = 3, end_lnum = 12, end_col = 4 }, + } + validate_preview(items) +end + +T['default_preview()']['has syntax highlighting in buffer'] = function() + child.cmd('edit ' .. real_file('a.lua')) + local buf_id_lua = child.api.nvim_get_current_buf() + child.cmd('edit ' .. real_file('Makefile')) + local buf_id_makefile = child.api.nvim_get_current_buf() + child.cmd('enew') + + local items = { + { text = 'Tree-sitter highlighting', bufnr = buf_id_lua }, + { text = 'Built-in syntax', bufnr = buf_id_makefile }, + } + validate_preview(items) +end + +T['default_preview()']['loads context in buffer'] = function() + child.cmd('edit ' .. real_file('b.txt')) + local buf_id = child.api.nvim_get_current_buf() + child.cmd('enew') + + start_with_items({ { text = 'Buffer', bufnr = buf_id } }) + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() +end + +T['default_preview()']['has fallback'] = function() + child.set_size(10, 40) + validate_preview({ -1, { text = 'Random table' } }) +end + +T['default_preview()']['respects `opts.n_context_lines`'] = function() + child.lua([[MiniPick.config.source.preview = function(buf_id, item) + return MiniPick.default_preview(buf_id, item, { n_context_lines = 2 }) + end]]) + local path = real_file('b.txt') + child.cmd('edit ' .. path) + local buf_id = child.api.nvim_get_current_buf() + child.cmd('enew') + + local items = { + -- File line + path .. ':4', + + -- Buffer line + { text = 'Buffer', bufnr = buf_id, lnum = 7 }, + } + validate_preview(items) +end + +T['default_preview()']['respects `opts.line_position`'] = new_set({ + parametrize = { { 'top' }, { 'center' }, { 'bottom' } }, +}, { + function(line_position) + child.lua('_G.line_position = ' .. vim.inspect(line_position)) + child.lua([[MiniPick.config.source.preview = function(buf_id, item) + return MiniPick.default_preview(buf_id, item, { line_position = _G.line_position }) + end]]) + local path = real_file('b.txt') + child.cmd('edit ' .. path) + local buf_id = child.api.nvim_get_current_buf() + child.cmd('enew') + + local items = { + -- File line + path .. ':10', + + -- Buffer line + { text = 'Buffer', bufnr = buf_id, lnum = 12 }, + } + validate_preview(items) + end, +}) + +T['default_preview()']['respects `source.cwd`'] = function() + local lua_cmd = string.format([[MiniPick.start({ source = { items = { 'b.txt' }, cwd = '%s' } })]], real_files_dir) + child.lua_notify(lua_cmd) + type_keys('') + child.expect_screenshot() +end + +T['default_choose()'] = new_set() + +local default_choose = forward_lua('MiniPick.default_choose') + +local choose_item = function(item) + start_with_items({ item }) + type_keys('') + eq(is_picker_active(), false) +end + +T['default_choose()']['works'] = function() + local path = real_file('b.txt') + choose_item(path) + validate_buf_name(0, path) +end + +T['default_choose()']['respects picker target window'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + local buf_id_1 = child.api.nvim_create_buf(false, true) + child.api.nvim_win_set_buf(win_id_1, buf_id_1) + local buf_id_2 = child.api.nvim_create_buf(false, true) + child.api.nvim_win_set_buf(win_id_2, buf_id_2) + + local path = real_file('b.txt') + start_with_items({ path }) + child.lua(string.format('MiniPick.set_picker_target_window(%d)', win_id_2)) + type_keys('') + + eq(child.api.nvim_win_get_buf(win_id_1), buf_id_1) + validate_buf_name(buf_id_1, '') + eq(child.api.nvim_win_get_buf(win_id_2), buf_id_2) + validate_buf_name(buf_id_2, path) +end + +T['default_choose()']['works without active picker'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + local path = real_file('b.txt') + default_choose(path) + + -- Should use current window as target + validate_buf_name(child.api.nvim_win_get_buf(win_id_1), path) + validate_buf_name(child.api.nvim_win_get_buf(win_id_2), '') +end + +T['default_choose()']['works for file path'] = function() + local validate = function(item, path, pos) + local win_id = child.api.nvim_get_current_win() + default_choose(item) + + local buf_id = child.api.nvim_win_get_buf(win_id) + validate_buf_name(buf_id, path) + if pos ~= nil then eq(child.api.nvim_win_get_cursor(win_id), pos) end + + -- Cleanup + child.api.nvim_buf_delete(buf_id, { force = true }) + end + + local path = real_file('b.txt') + + -- Path + validate(path, path, { 1, 0 }) + validate({ text = path, path = path }, path, { 1, 0 }) + + -- Path with line + validate(path .. ':4', path, { 4, 0 }) + validate({ text = path, path = path, lnum = 6 }, path, { 6, 0 }) + + -- Path with position + validate(path .. ':8:2', path, { 8, 1 }) + validate({ text = path, path = path, lnum = 10, col = 4 }, path, { 10, 3 }) + + -- Path with region + validate({ text = path, path = path, lnum = 12, col = 5, end_lnum = 14, end_col = 3 }, path, { 12, 4 }) +end + +T['default_choose()']['reuses opened listed buffer for file path'] = function() + local path = real_file('b.txt') + child.cmd('edit ' .. path) + local buf_id_path = child.api.nvim_get_current_buf() + validate_buf_name(buf_id_path, path) + set_cursor(5, 3) + + local buf_id_alt = child.api.nvim_create_buf(true, false) + + local validate = function(pos) + eq(child.api.nvim_win_get_buf(0), buf_id_path) + validate_buf_name(buf_id_path, path) + eq(child.api.nvim_win_get_cursor(0), pos) + end + + -- Reuses without setting cursor + child.api.nvim_set_current_buf(buf_id_alt) + default_choose(path) + validate({ 5, 3 }) + + -- Reuses with setting cursor + child.api.nvim_set_current_buf(buf_id_alt) + default_choose(path .. ':7:2') + validate({ 7, 1 }) + + -- Doesn't reuse if unlisted + child.api.nvim_set_current_buf(buf_id_alt) + child.cmd('bdelete ' .. buf_id_path) + eq(child.api.nvim_buf_get_option(buf_id_path, 'buflisted'), false) + default_choose(path) + validate({ 1, 0 }) + eq(child.api.nvim_buf_get_option(buf_id_path, 'buflisted'), true) +end + +T['default_choose()']['works for directory path'] = function() + local validate = function(item, path) + local buf_id_init = child.api.nvim_get_current_buf() + default_choose(item) + + local buf_id_cur = child.api.nvim_get_current_buf() + eq(child.bo.filetype, 'netrw') + validate_buf_name(buf_id_init, path) + + -- Cleanup + child.api.nvim_buf_delete(buf_id_init, { force = true }) + child.api.nvim_buf_delete(buf_id_cur, { force = true }) + end + + validate(test_dir, test_dir) + validate({ text = test_dir, path = test_dir }, test_dir) +end + +T['default_choose()']['works for buffer'] = function() + local buf_id_tmp = child.api.nvim_create_buf(false, true) + + local setup_buffer = function(pos) + local buf_id = child.api.nvim_create_buf(true, false) + child.api.nvim_buf_set_lines(buf_id, 0, -1, false, vim.fn['repeat']({ 'aaaaaaaaaaaaaaaaaaaa' }, 20)) + + local cur_buf = child.api.nvim_win_get_buf(0) + child.api.nvim_set_current_buf(buf_id) + child.api.nvim_win_set_cursor(0, pos) + child.api.nvim_win_set_buf(0, cur_buf) + + return buf_id + end + + local validate = function(item, buf_id, pos) + local win_id = child.api.nvim_get_current_win() + child.api.nvim_win_set_buf(0, buf_id_tmp) + + default_choose(item) + + eq(child.api.nvim_win_get_buf(win_id), buf_id) + if pos ~= nil then eq(child.api.nvim_win_get_cursor(win_id), pos) end + + -- Cleanup + child.api.nvim_buf_delete(buf_id, { force = true }) + end + + local buf_id + + -- Buffer without position should reuse current cursor + buf_id = setup_buffer({ 1, 1 }) + validate(buf_id, buf_id, { 1, 1 }) + + buf_id = setup_buffer({ 2, 2 }) + validate(tostring(buf_id), buf_id, { 2, 2 }) + + -- Buffer in table + buf_id = setup_buffer({ 3, 3 }) + validate({ text = 'buffer', bufnr = buf_id }, buf_id, { 3, 3 }) + + buf_id = setup_buffer({ 4, 4 }) + validate({ text = 'buffer', buf_id = buf_id }, buf_id, { 4, 4 }) + + buf_id = setup_buffer({ 5, 5 }) + validate({ text = 'buffer', buf = buf_id }, buf_id, { 5, 5 }) + + -- Buffer with line + buf_id = setup_buffer({ 6, 6 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 7 }, buf_id, { 7, 0 }) + + -- Buffer with position + buf_id = setup_buffer({ 6, 6 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 8, col = 8 }, buf_id, { 8, 7 }) + + -- Buffer with region + buf_id = setup_buffer({ 6, 6 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 9, col = 9, end_lnum = 10, end_col = 8 }, buf_id, { 9, 8 }) + + -- Already shown buffer + local setup_current_buf = function(pos) + child.api.nvim_buf_set_lines(0, 0, -1, false, vim.fn['repeat']({ 'aaaaaaaaaaaaaaaaaaaa' }, 20)) + child.api.nvim_win_set_cursor(0, pos) + return child.api.nvim_get_current_buf() + end + + buf_id = setup_current_buf({ 11, 11 }) + validate(buf_id, buf_id, { 11, 11 }) + + buf_id = setup_current_buf({ 12, 12 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 13 }, buf_id, { 13, 0 }) + + buf_id = setup_current_buf({ 12, 12 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 14, col = 14 }, buf_id, { 14, 13 }) + + buf_id = setup_current_buf({ 12, 12 }) + validate({ text = 'buffer', bufnr = buf_id, lnum = 15, col = 15, end_lnum = 16, end_col = 14 }, buf_id, { 15, 14 }) +end + +T['default_choose()']['ensures valid target window'] = function() + local choose_with_bad_target_window = function(item) + child.cmd('botright wincmd v') + local win_id = child.api.nvim_get_current_win() + + start_with_items({ item }) + local lua_cmd = string.format([[vim.api.nvim_win_call(%d, function() vim.cmd('close') end)]], win_id) + child.lua(lua_cmd) + + type_keys('') + end + + -- Path + local path = real_file('b.txt') + choose_with_bad_target_window(path) + validate_buf_name(child.api.nvim_get_current_buf(), path) + + -- Buffer + local buf_id = child.api.nvim_create_buf(true, false) + choose_with_bad_target_window({ text = 'buffer', bufnr = buf_id }) + eq(child.api.nvim_get_current_buf(), buf_id) +end + +T['default_choose()']['centers cursor'] = function() + local validate = function(item, ref_topline) + choose_item(item) + eq(child.fn.line('w0'), ref_topline) + end + + -- Path + local path = real_file('b.txt') + validate({ text = path, path = path, lnum = 10 }, 4) + + -- Buffer + local buf_id = child.api.nvim_create_buf(true, false) + child.api.nvim_buf_set_lines(buf_id, 0, -1, false, vim.fn['repeat']({ 'aaaaaaaaaa' }, 100)) + validate({ text = 'buffer', bufnr = buf_id, lnum = 12 }, 6) +end + +T['default_choose()']['opens just enough folds'] = function() + child.api.nvim_buf_set_lines(0, 0, -1, false, vim.fn['repeat']({ 'aaaaaaaaaa' }, 100)) + child.cmd('2,3fold') + child.cmd('12,13fold') + + eq(child.fn.foldclosed(2), 2) + eq(child.fn.foldclosed(3), 2) + eq(child.fn.foldclosed(12), 12) + eq(child.fn.foldclosed(13), 12) + + default_choose({ text = 'buffer', bufnr = child.api.nvim_get_current_buf(), lnum = 12 }) + + eq(child.fn.foldclosed(2), 2) + eq(child.fn.foldclosed(3), 2) + eq(child.fn.foldclosed(12), -1) + eq(child.fn.foldclosed(13), -1) +end + +T['default_choose()']['has print fallback'] = function() + choose_item({ text = 'regular-table' }) + eq(child.cmd_capture('messages'), '\n{\n text = "regular-table"\n}') +end + +T['default_choose()']['does nothing for `nil` input'] = function() + expect.no_error(function() default_choose() end) + eq(child.cmd_capture('messages'), '') +end + +T['default_choose_marked()'] = new_set() + +local default_choose_marked = forward_lua('MiniPick.default_choose_marked') + +local validate_qfitem = function(input, ref) + local eq_if_nonnil = function(x, y) + if y ~= nil then eq(x, y) end + end + + eq_if_nonnil(input.bufnr, ref.bufnr) + if ref.filename ~= nil then validate_buf_name(input.bufnr, ref.filename) end + eq_if_nonnil(input.lnum, ref.lnum) + eq_if_nonnil(input.col, ref.col) + eq_if_nonnil(input.end_lnum, ref.end_lnum) + eq_if_nonnil(input.end_col, ref.end_col) + eq_if_nonnil(input.text, ref.text) +end + +T['default_choose_marked()']['works'] = function() + local path = real_file('b.txt') + start_with_items({ path }) + type_keys('', '') + eq(is_picker_active(), false) + + -- Should create and open quickfix list + eq(#child.api.nvim_list_wins(), 2) + eq(child.bo.filetype, 'qf') + + local qflist = child.fn.getqflist() + eq(#qflist, 1) + validate_qfitem(qflist[1], { filename = path, lnum = 1, col = 1, end_lnum = 0, end_col = 0, text = '' }) +end + +T['default_choose_marked()']['creates proper title'] = function() + local validate = function(keys, title) + local path = real_file('b.txt') + start_with_items({ path }, 'Picker name') + type_keys(keys, '', '') + eq(is_picker_active(), false) + eq(child.fn.getqflist({ title = true }).title, title) + end + + validate({}, 'Picker name') + validate({ 'b', '.', 't' }, 'Picker name : b.t') +end + +T['default_choose_marked()']['sets as last list'] = function() + local path = real_file('b.txt') + child.fn.setqflist({}, ' ', { items = { { filename = path, lnum = 2, col = 2 } }, nr = '$' }) + child.fn.setqflist({}, ' ', { items = { { filename = path, lnum = 3, col = 3 } }, nr = '$' }) + child.cmd('colder') + + start_with_items({ path }) + type_keys('', '') + local list_data = child.fn.getqflist({ all = true }) + validate_qfitem(list_data.items[1], { filename = path, lnum = 1, col = 1 }) + eq(list_data.nr, 3) +end + +T['default_choose_marked()']['works without active picker'] = function() + local path_1, path_2 = real_file('b.txt'), real_file('LICENSE') + default_choose_marked({ path_1, path_2 }) + + eq(#child.api.nvim_list_wins(), 2) + eq(child.bo.filetype, 'qf') + + local list_data = child.fn.getqflist({ all = true }) + eq(#list_data.items, 2) + validate_qfitem(list_data.items[1], { filename = path_1, lnum = 1, col = 1, end_lnum = 0, end_col = 0, text = '' }) + validate_qfitem(list_data.items[2], { filename = path_2, lnum = 1, col = 1, end_lnum = 0, end_col = 0, text = '' }) + + eq(list_data.title, '') +end + +T['default_choose_marked()']['creates quickfix list from file/buffer positions'] = function() + local path = real_file('b.txt') + local buf_id = child.api.nvim_create_buf(true, false) + local buf_id_scratch = child.api.nvim_create_buf(false, true) + + local items = { + -- File path + path, + + { text = 'filepath', path = path }, + + path .. ':3', + { text = path, path = path, lnum = 4 }, + + path .. ':5:5', + path .. ':6:6:' .. 'extra text', + { text = path, path = path, lnum = 7, col = 7 }, + + { text = path, path = path, lnum = 8, col = 8, end_lnum = 9, end_col = 9 }, + { text = path, path = path, lnum = 8, col = 9, end_lnum = 9 }, + + -- Buffer + buf_id, + tostring(buf_id), + { text = 'buffer', bufnr = buf_id }, + + buf_id_scratch, + + { text = 'buffer', bufnr = buf_id, lnum = 5 }, + + { text = 'buffer', bufnr = buf_id, lnum = 6, col = 6 }, + + { text = 'buffer', bufnr = buf_id, lnum = 7, col = 7, end_lnum = 8, end_col = 8 }, + { text = 'buffer', bufnr = buf_id, lnum = 7, col = 8, end_lnum = 8 }, + } + + start_with_items(items) + type_keys('', '') + local qflist = child.fn.getqflist() + eq(#qflist, #items) + + validate_qfitem(qflist[1], { filename = path, lnum = 1, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[2], { filename = path, lnum = 1, col = 1, end_lnum = 0, end_col = 0, text = 'filepath' }) + validate_qfitem(qflist[3], { filename = path, lnum = 3, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[4], { filename = path, lnum = 4, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[5], { filename = path, lnum = 5, col = 5, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[6], { filename = path, lnum = 6, col = 6, end_lnum = 0, end_col = 0, text = 'extra text' }) + validate_qfitem(qflist[7], { filename = path, lnum = 7, col = 7, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[8], { filename = path, lnum = 8, col = 8, end_lnum = 9, end_col = 9 }) + validate_qfitem(qflist[9], { filename = path, lnum = 8, col = 9, end_lnum = 9, end_col = 0 }) + + validate_qfitem(qflist[10], { bufnr = buf_id, lnum = 1, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[11], { bufnr = buf_id, lnum = 1, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[12], { bufnr = buf_id, lnum = 1, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[13], { bufnr = buf_id_scratch, lnum = 1, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[14], { bufnr = buf_id, lnum = 5, col = 1, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[15], { bufnr = buf_id, lnum = 6, col = 6, end_lnum = 0, end_col = 0 }) + validate_qfitem(qflist[16], { bufnr = buf_id, lnum = 7, col = 7, end_lnum = 8, end_col = 8 }) + validate_qfitem(qflist[17], { bufnr = buf_id, lnum = 7, col = 8, end_lnum = 8, end_col = 0 }) +end + +T['default_choose_marked()']['falls back to choosing first item'] = function() + child.lua_notify( + [[MiniPick.start({source = { items = { -1, { text = 'some_table' }, -3 }, choose = function(item) _G.chosen_item = item end, }})]] + ) + type_keys('', '', '', '', '') + eq(is_picker_active(), false) + + eq(child.lua_get('_G.chosen_item'), { text = 'some_table' }) + + -- Can also be called without active picker and error + expect.no_error(function() default_choose_marked({ -1, { text = 'some_table' } }) end) +end + +T['default_choose_marked()']['works for edge case input'] = function() + expect.error(default_choose_marked, '`items`.*array') + expect.no_error(function() default_choose_marked({}) end) +end + +T['default_choose_marked()']['respects `opts.list_type`'] = function() + local win_id = child.api.nvim_get_current_win() + local buf_id = child.api.nvim_create_buf(true, false) + + child.lua([[MiniPick.config.source.choose_marked = function(items) + return MiniPick.default_choose_marked(items, { list_type = 'location' }) + end]]) + start_with_items({ { bufnr = buf_id } }, 'list_type test') + type_keys('', '') + eq(is_picker_active(), false) + + -- Should create and open location list + eq(#child.api.nvim_list_wins(), 2) + eq(child.bo.filetype, 'qf') + + local loclist = child.fn.getloclist(win_id, { all = true }) + eq(#loclist.items, 1) + validate_qfitem(loclist.items[1], { bufnr = buf_id, lnum = 1, col = 1, end_lnum = 0, end_col = 0, text = '' }) + + eq(loclist.title, 'list_type test') + + -- No quickfix lists should be created + eq(child.fn.getqflist({ nr = true }).nr, 0) +end + +T['default_choose_marked()']['ensures valid target window for location list'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + + local buf_id = child.api.nvim_create_buf(true, false) + child.lua([[MiniPick.config.source.choose_marked = function(items) + return MiniPick.default_choose_marked(items, { list_type = 'location' }) + end]]) + + start_with_items({ { bufnr = buf_id } }, 'ensure valid window') + local lua_cmd = string.format([[vim.api.nvim_win_call(%d, function() vim.cmd('close') end)]], win_id_1) + child.lua(lua_cmd) + type_keys('', '') + eq(is_picker_active(), false) + + eq(child.fn.getloclist(win_id_2, { title = true }).title, 'ensure valid window') +end + +T['ui_select()'] = new_set() + +local ui_select = function(items, opts, on_choice_str) + opts = opts or {} + on_choice_str = on_choice_str or 'function(...) _G.args = { ... } end' + local lua_cmd = string.format('MiniPick.ui_select(%s, %s, %s)', vim.inspect(items), vim.inspect(opts), on_choice_str) + child.lua_notify(lua_cmd) +end + +T['ui_select()']['works'] = function() + ui_select({ -1, -2 }) + child.expect_screenshot() + type_keys('', '') + eq(child.lua_get('_G.args'), { -2, 2 }) +end + +T['ui_select()']['calls `on_choice(nil)` in case of abort'] = function() + ui_select({ -1, -2 }) + type_keys('') + eq(child.lua_get('_G.args'), {}) +end + +T['ui_select()']['preserves target window after `on_choice`'] = function() + local _, win_id_2 = setup_windows_pair() + + local on_choice_str = string.format('function() vim.api.nvim_set_current_win(%d) end', win_id_2) + ui_select({ -1, -2 }, {}, on_choice_str) + type_keys('') + eq(child.api.nvim_get_current_win(), win_id_2) +end + +T['ui_select()']['respects `opts.prompt` and `opts.kind`'] = function() + local validate = function(opts, source_name) + ui_select({ -1, -2 }, opts) + validate_picker_option('source.name', source_name) + stop() + end + + -- Should try using use both as source name (preferring `kind` over `prompt`) + validate({ prompt = 'Prompt' }, 'Prompt') + validate({ prompt = 'Prompt', kind = 'Kind' }, 'Kind') +end + +T['ui_select()']['respects `opts.format_item`'] = function() + child.lua_notify([[MiniPick.ui_select( + { { var = 'abc' }, { var = 'def' } }, + { format_item = function(x) return x.var end }, + function(...) _G.args = { ... } end + )]]) + + -- Should use formatted output as regular stritems + eq(get_picker_stritems(), { 'abc', 'def' }) + type_keys('d', '') + eq(child.lua_get('_G.args'), { { var = 'def' }, 2 }) +end + +T['ui_select()']['shows only original item in preview'] = function() + child.lua_notify([[MiniPick.ui_select({ { var = 'abc' } }, { format_item = function(x) return x.var end })]]) + type_keys('') + child.expect_screenshot() +end + +T['ui_select()']['respects `opts.preview_item`'] = function() + child.lua_notify([[MiniPick.ui_select( + { { var = 'abc' } }, + { + format_item = function(x) return x.var end, + preview_item = function(x) return { 'My preview', 'Var = ' .. x.var } end, + } + )]]) + type_keys('') + child.expect_screenshot() +end + +T['builtin.files()'] = new_set({ hooks = { pre_case = mock_spawn } }) + +local builtin_files = forward_lua_notify('MiniPick.builtin.files') + +T['builtin.files()']['works'] = function() + child.set_size(10, 60) + mock_fn_executable({ 'rg' }) + local items = { real_file('b.txt'), real_file('LICENSE'), test_dir } + mock_cli_return(items) + + child.lua_notify('_G.file_item = MiniPick.builtin.files()') + + -- Should use icons by default + child.expect_screenshot() + + -- Should set correct name + validate_picker_option('source.name', 'Files (rg)') + + -- Should return chosen value + type_keys('') + eq(child.lua_get('_G.file_item'), items[1]) +end + +T['builtin.files()']['correctly chooses default tool'] = function() + local validate = function(executables, ref_tool) + mock_fn_executable(executables) + mock_cli_return({ real_file('b.txt') }) + builtin_files() + if ref_tool ~= 'fallback' then eq(child.lua_get('_G.spawn_log[1].executable'), ref_tool) end + validate_picker_option('source.name', string.format('Files (%s)', ref_tool)) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + validate({ 'rg', 'fd', 'git' }, 'rg') + validate({ 'fd', 'git' }, 'fd') + validate({ 'git' }, 'git') + validate({}, 'fallback') +end + +T['builtin.files()']['respects `local_opts.tool`'] = function() + local validate = function(tool, ref_args) + mock_fn_executable({ tool }) + mock_cli_return({}) + builtin_files({ tool = tool }) + local spawn_data = child.lua_get('_G.spawn_log[1]') + eq(spawn_data.executable, tool) + + -- Tool should be called with proper arguments + validate_contains_all(spawn_data.options.args, ref_args) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + validate('rg', { '--files', '--hidden', '--no-follow' }) + validate('fd', { '--type=f', '--hidden', '--no-follow' }) + validate('git', { 'ls-files', '--cached', '--others' }) +end + +T['builtin.files()']['has fallback tool'] = function() + if child.fn.has('nvim-0.9') == 0 then + local f = function() child.lua([[MiniPick.builtin.files({ tool = 'fallback' })]]) end + expect.error(f, 'Tool "fallback" of `files`.*0%.9') + return + end + + local cwd = join_path(test_dir, 'builtin-tests') + builtin_files({ tool = 'fallback' }, { source = { cwd = cwd } }) + validate_picker_option('source.cwd', full_path(cwd)) + + -- Sleep because fallback is async + sleep(5) + eq(get_picker_items(), { 'file', 'dir1/file1-1', 'dir1/file1-2', 'dir2/file2-1' }) +end + +T['builtin.files()']['respects `source.show` from config'] = function() + child.set_size(10, 60) + + -- A recommended way to disable icons + child.lua('MiniPick.config.source.show = MiniPick.default_show') + mock_fn_executable({ 'rg' }) + mock_cli_return({ real_file('b.txt'), test_dir }) + builtin_files() + child.expect_screenshot() +end + +T['builtin.files()']['respects `opts`'] = function() + mock_fn_executable({ 'rg' }) + mock_cli_return({ real_file('b.txt') }) + builtin_files({}, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +T['builtin.files()']['respects `opts.source.cwd` for cli spawn'] = function() + mock_fn_executable({ 'rg' }) + mock_cli_return({}) + builtin_files({}, { source = { cwd = test_dir } }) + + local test_dir_absolute = full_path(test_dir) + validate_picker_option('source.cwd', test_dir_absolute) + eq(get_spawn_log()[1].options.cwd, test_dir_absolute) +end + +T['builtin.grep()'] = new_set({ hooks = { pre_case = mock_spawn } }) + +local builtin_grep = forward_lua_notify('MiniPick.builtin.grep') + +T['builtin.grep()']['works'] = function() + child.set_size(10, 70) + mock_fn_executable({ 'rg' }) + local items = { real_file('a.lua') .. ':3:3:a', real_file('b.txt') .. ':1:1:b' } + mock_cli_return(items) + + child.lua_notify([[_G.grep_item = MiniPick.builtin.grep()]]) + -- - By default asks for pattern interactively + type_keys('b', '') + + -- Should use icons by default + child.expect_screenshot() + + -- Should set correct name + validate_picker_option('source.name', 'Grep (rg)') + + -- Should return chosen value + type_keys('') + eq(child.lua_get('_G.grep_item'), items[1]) +end + +T['builtin.grep()']['correctly chooses default tool'] = function() + local validate = function(executables, ref_tool) + mock_fn_executable(executables) + mock_cli_return({ real_file('b.txt') .. ':3:3:b' }) + builtin_grep({ pattern = 'b' }) + if ref_tool ~= 'fallback' then eq(child.lua_get('_G.spawn_log[1].executable'), ref_tool) end + validate_picker_option('source.name', string.format('Grep (%s)', ref_tool)) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + validate({ 'rg', 'git' }, 'rg') + validate({ 'git' }, 'git') + validate({}, 'fallback') +end + +T['builtin.grep()']['respects `local_opts.tool`'] = new_set({ parametrize = { { 'default' }, { 'supplied' } } }, { + test = function(pattern_type) + local pattern, keys + if pattern_type == 'default' then + keys = { 'test', '' } + elseif pattern_type == 'supplied' then + pattern = 'test' + end + + local validate = function(tool, ref_args) + mock_fn_executable({ tool }) + mock_cli_return({}) + builtin_grep({ tool = tool, pattern = pattern }) + type_keys(keys) + + local spawn_data = child.lua_get('_G.spawn_log[1]') + eq(spawn_data.executable, tool) + + -- Tool should be called with proper arguments + validate_contains_all(spawn_data.options.args, ref_args) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + validate('rg', { '--column', '--line-number', '--no-heading', '--hidden', '--smart-case', '--', 'test' }) + validate('git', { 'grep', '--column', '--line-number', '--', 'test' }) + end, +}) + +T['builtin.grep()']['has fallback tool'] = new_set({ parametrize = { { 'default' }, { 'supplied' } } }, { + test = function(pattern_type) + if child.fn.has('nvim-0.9') == 0 then + local f = function() child.lua([[MiniPick.builtin.grep({ tool = 'fallback', pattern = 'x' })]]) end + expect.error(f, 'Tool "fallback" of `grep`.*0%.9') + return + end + + local pattern, keys + if pattern_type == 'default' then + keys = { 'aaa', '' } + elseif pattern_type == 'supplied' then + pattern = 'aaa' + end + + local cwd = join_path(test_dir, 'builtin-tests') + builtin_grep({ tool = 'fallback', pattern = pattern }, { source = { cwd = cwd } }) + type_keys(keys) + validate_picker_option('source.cwd', full_path(cwd)) + + -- Sleep because fallback is async + sleep(5) + eq(get_picker_items(), { 'file:3:1:aaa', 'dir1/file1-1:3:1:aaa', 'dir1/file1-2:3:1:aaa', 'dir2/file2-1:3:1:aaa' }) + end, +}) + +T['builtin.grep()']['respects `source.show` from config'] = function() + child.set_size(10, 70) + + -- A recommended way to disable icons + child.lua('MiniPick.config.source.show = MiniPick.default_show') + mock_fn_executable({ 'rg' }) + mock_cli_return({ real_file('b.txt') .. ':1:1' }) + builtin_grep({ pattern = 'b' }) + child.expect_screenshot() +end + +T['builtin.grep()']['respects `opts`'] = function() + mock_fn_executable({ 'rg' }) + mock_cli_return({ real_file('b.txt') .. ':1:1' }) + builtin_grep({ pattern = 'b' }, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +T['builtin.grep()']['respects `opts.source.cwd` for cli spawn'] = function() + mock_fn_executable({ 'rg' }) + mock_cli_return({}) + builtin_grep({ pattern = 'b' }, { source = { cwd = test_dir } }) + + local test_dir_absolute = full_path(test_dir) + validate_picker_option('source.cwd', test_dir_absolute) + eq(get_spawn_log()[1].options.cwd, test_dir_absolute) +end + +T['builtin.grep()']['can have empty string pattern interactively'] = function() + mock_fn_executable({ 'rg' }) + mock_cli_return({}) + builtin_grep({ tool = 'rg' }) + type_keys('') + + local args = child.lua_get('_G.spawn_log[1]').options.args + eq({ args[#args - 1], args[#args] }, { '--', '' }) +end + +T['builtin.grep_live()'] = new_set({ hooks = { pre_case = mock_spawn } }) + +local builtin_grep_live = forward_lua_notify('MiniPick.builtin.grep_live') + +local validate_last_grep_pattern = function(pattern) + local log = get_spawn_log() + local spawn_args = log[#log].options.args + eq({ spawn_args[#spawn_args - 1], spawn_args[#spawn_args] }, { '--', pattern }) +end + +T['builtin.grep_live()']['works'] = function() + child.set_size(10, 70) + mock_fn_executable({ 'rg' }) + local items = { real_file('a.lua') .. ':3:3:a', real_file('b.txt') .. ':1:1:b' } + + -- Should show no items for empty query + child.lua_notify([[_G.grep_live_item = MiniPick.builtin.grep_live()]]) + eq(get_picker_items(), {}) + + -- Should grep pattern after every query update + mock_cli_return(items) + type_keys('b') + eq(get_picker_items(), items) + validate_last_grep_pattern('b') + + mock_cli_return({ items[2] }) + type_keys('t') + eq(get_picker_items(), { items[2] }) + validate_last_grep_pattern('bt') + + -- Should use icons by default + child.expect_screenshot() + + -- Should set correct name + validate_picker_option('source.name', 'Grep live (rg)') + + -- Should return chosen value + type_keys('') + eq(child.lua_get('_G.grep_live_item'), items[2]) +end + +T['builtin.grep_live()']['always shows no items for empty query'] = function() + mock_fn_executable({ 'rg' }) + local items = { real_file('a.lua') .. ':3:3:a', real_file('b.txt') .. ':1:1:b' } + + -- Showing empty query should be done without extra spawn + mock_cli_return(items) + builtin_grep_live() + eq(get_picker_items(), {}) + eq(#get_spawn_log(), 0) + + mock_cli_return(items) + type_keys('b') + eq(get_picker_items(), items) + eq(#get_spawn_log(), 1) + + mock_cli_return({ items[1] }) + type_keys('') + eq(get_picker_items(), {}) + eq(#get_spawn_log(), 1) +end + +T['builtin.grep_live()']['kills grep process on every non-empty query update'] = function() + mock_fn_executable({ 'rg' }) + local items = { real_file('a.lua') .. ':3:3:a', real_file('b.txt') .. ':1:1:b' } + + builtin_grep_live() + eq(get_process_log(), {}) + + mock_cli_return(items) + type_keys('b') + -- - No process to kill before making query non-empty + eq(get_process_log(), { 'Stdout Stdout_1 was closed.', 'Process Pid_1 was closed.' }) + clear_process_log() + + mock_cli_return({ items[2] }) + type_keys('y') + --Stylua: ignore + eq(get_process_log(), { 'Process Pid_1 was killed.', 'Stdout Stdout_2 was closed.', 'Process Pid_2 was closed.' }) + clear_process_log() + + type_keys('') + eq(get_process_log(), { 'Process Pid_2 was killed.' }) +end + +T['builtin.grep_live()']['works with programmatic query update'] = function() + mock_fn_executable({ 'rg' }) + builtin_grep_live() + + mock_cli_return({ real_file('b.txt') .. ':1:1:b' }) + set_picker_query({ 'b', 't' }) + validate_last_grep_pattern('bt') + + set_picker_query({ 'ab', '', 'cd' }) + validate_last_grep_pattern('abcd') +end + +T['builtin.grep_live()']['correctly chooses default tool'] = function() + local validate = function(executables, ref_tool) + mock_fn_executable(executables) + mock_cli_return({ real_file('b.txt') .. ':3:3:b' }) + builtin_grep_live() + type_keys('b') + eq(child.lua_get('_G.spawn_log[1].executable'), ref_tool) + validate_picker_option('source.name', string.format('Grep live (%s)', ref_tool)) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + -- Needs executable non-fallback "grep" tool + validate({ 'rg', 'git' }, 'rg') + validate({ 'git' }, 'git') + + mock_fn_executable({}) + expect.error(function() child.lua('MiniPick.builtin.grep_live()') end, '`grep_live`.*non%-fallback') +end + +T['builtin.grep_live()']['respects `local_opts.tool`'] = function() + local validate = function(tool, ref_args) + mock_fn_executable({ tool }) + mock_cli_return({}) + builtin_grep_live({ tool = tool }) + type_keys('b') + + local spawn_data = child.lua_get('_G.spawn_log[1]') + eq(spawn_data.executable, tool) + + -- Tool should be called with proper arguments + validate_contains_all(spawn_data.options.args, ref_args) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + validate('rg', { '--column', '--line-number', '--no-heading', '--hidden', '--smart-case', '--', 'b' }) + validate('git', { 'grep', '--column', '--line-number', '--', 'b' }) + + -- Should not accept "fallback" tool + mock_fn_executable({}) + expect.error( + function() child.lua([[MiniPick.builtin.grep_live({ tool = 'fallback' })]]) end, + '`grep_live`.*non%-fallback' + ) +end + +T['builtin.grep_live()']['respects `source.show` from config'] = function() + child.set_size(10, 70) + + -- A recommended way to disable icons + child.lua('MiniPick.config.source.show = MiniPick.default_show') + mock_fn_executable({ 'rg' }) + builtin_grep_live() + mock_cli_return({ real_file('b.txt') .. ':1:1' }) + type_keys('b') + child.expect_screenshot() +end + +T['builtin.grep_live()']['respects `opts`'] = function() + mock_fn_executable({ 'rg' }) + builtin_grep_live({}, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +T['builtin.grep_live()']['respects `opts.source.cwd` for cli spawn'] = function() + mock_fn_executable({ 'rg' }) + builtin_grep_live({}, { source = { cwd = test_dir } }) + mock_cli_return({ real_file('b.txt') .. ':1:1' }) + type_keys('b') + + local test_dir_absolute = full_path(test_dir) + validate_picker_option('source.cwd', test_dir_absolute) + eq(get_spawn_log()[1].options.cwd, test_dir_absolute) +end + +T['builtin.help()'] = new_set() + +local builtin_help = forward_lua_notify('MiniPick.builtin.help') + +T['builtin.help()']['works'] = function() + child.lua_notify('_G.help_item = MiniPick.builtin.help()') + child.expect_screenshot() + + -- Should set correct name + validate_picker_option('source.name', 'Help') + + -- Should return chosen value + local item = get_picker_matches().current + type_keys('') + eq(child.lua_get('_G.help_item'), item) + + -- Should open help page as choosing + child.expect_screenshot() +end + +T['builtin.help()']['has proper preview'] = function() + child.set_size(15, 80) + + -- Shouldn't have side effects for serach pattern and `v:hlsearch` + child.api.nvim_buf_set_lines(0, 0, -1, false, { 'aa', 'bb', 'aa' }) + type_keys('/', 'aa', '') + child.cmd('let v:hlsearch=0') + + builtin_help() + type_keys('') + child.expect_screenshot() + + eq(child.v.hlsearch, 0) + eq(child.fn.getreg('/'), 'aa') +end + +T['builtin.help()']['works for help tags with special characters'] = function() + child.set_size(15, 80) + builtin_help() + set_picker_query({ 'c_CTRL-K' }) + type_keys('') + child.expect_screenshot() +end + +T['builtin.help()']['works when help window is alreay opened'] = function() + -- Open non-current help window + child.cmd('help') + child.cmd('wincmd w') + + builtin_help() + + -- Should open help in already opened help window (just like `:help`) + type_keys('') + child.expect_screenshot() + eq(#child.api.nvim_list_wins(), 2) +end + +T['builtin.help()']['can be properly aborted'] = function() + builtin_help() + type_keys('') + eq(#child.api.nvim_list_wins(), 1) +end + +T['builtin.help()']['handles consecutive applications'] = function() + builtin_help() + set_picker_query({ ':help' }) + type_keys('') + + builtin_help() + set_picker_query({ ':helpg' }) + type_keys('') + + child.expect_screenshot() +end + +T['builtin.help()']['respects `opts`'] = function() + builtin_help({}, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +local mock_opened_buffers = function() + child.cmd('edit ' .. real_file('b.txt')) + child.api.nvim_create_buf(true, false) + child.api.nvim_create_buf(false, true) + child.cmd('edit ' .. real_file('LICENSE')) +end + +T['builtin.buffers()'] = new_set({ hooks = { pre_case = mock_opened_buffers } }) + +local builtin_buffers = forward_lua_notify('MiniPick.builtin.buffers') + +T['builtin.buffers()']['works'] = function() + child.set_size(10, 70) + + -- Should show no items for empty query + child.lua_notify([[_G.buffers_item = MiniPick.builtin.buffers()]]) + + -- Should use icons by default + child.expect_screenshot() + + -- Should set correct name + validate_picker_option('source.name', 'Buffers') + + -- Should return chosen value + local item = get_picker_matches().current + type_keys('') + eq(child.lua_get('_G.buffers_item'), item) +end + +T['builtin.buffers()']['respects `local_opts.include_current`'] = function() + child.set_size(10, 70) + builtin_buffers({ include_current = false }) + child.expect_screenshot() +end + +T['builtin.buffers()']['respects `local_opts.include_unlisted`'] = function() + builtin_buffers({ include_unlisted = true }) + child.expect_screenshot() +end + +T['builtin.buffers()']['respects `source.show` from config'] = function() + -- A recommended way to disable icons + child.lua('MiniPick.config.source.show = MiniPick.default_show') + builtin_buffers() + child.expect_screenshot() +end + +T['builtin.buffers()']['respects `opts`'] = function() + builtin_buffers({}, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +T['builtin.cli()'] = new_set({ hooks = { pre_case = mock_spawn } }) + +local builtin_cli = forward_lua_notify('MiniPick.builtin.cli') + +T['builtin.cli()']['works'] = function() + mock_cli_return({ 'aa', 'bb' }) + child.lua_notify([[_G.cli_item = MiniPick.builtin.cli({ command = { 'echo', 'xx\nyy' } })]]) + + -- - Sleep as items are set inside `schedule_wrap`ed function + sleep(1) + eq(get_picker_items(), { 'aa', 'bb' }) + + -- Should set correct name + validate_picker_option('source.name', 'CLI (echo)') + + -- Should return chosen value + type_keys('') + eq(child.lua_get('_G.cli_item'), 'aa') +end + +T['builtin.cli()']['respects `local_opts.postprocess`'] = function() + mock_cli_return({ 'aa', 'bb' }) + child.lua([[_G.postprocess = function(...) _G.args = { ... }; return { 'x', 'y', 'z' } end]]) + child.lua_notify([[MiniPick.builtin.cli({ command = { 'echo', 'xx\nyy' }, postprocess = postprocess })]]) + sleep(1) + eq(child.lua_get('_G.args'), { { 'aa', 'bb' } }) + eq(get_picker_items(), { 'x', 'y', 'z' }) +end + +T['builtin.cli()']['respects `local_opts.spawn_opts`'] = function() + builtin_cli({ command = { 'echo', 'aa\nbb' }, spawn_opts = { env = { AAA = 'xxx' } } }) + eq(get_spawn_log()[1].options, { args = { 'aa\nbb' }, env = { AAA = 'xxx' } }) +end + +T['builtin.cli()']['respects `opts.source.cwd` for cli spawn'] = function() + local command = { 'echo', 'aa\nbb' } + local test_dir_absolute = full_path(test_dir) + + local validate = function(local_opts, opts, ref_cwd, source_cwd) + builtin_cli(local_opts, opts) + validate_picker_option('source.cwd', source_cwd or ref_cwd) + eq(get_spawn_log()[1].options.cwd, ref_cwd) + + -- Cleanup + type_keys('') + clear_spawn_log() + end + + -- Should use it as `spawn_opts.cwd` if it is not present + validate({ command = command }, { source = { cwd = test_dir } }, test_dir_absolute) + validate( + { command = command, spawn_opts = { cwd = real_files_dir } }, + { source = { cwd = test_dir } }, + full_path(real_files_dir), + test_dir_absolute + ) +end + +T['builtin.cli()']['respects `opts`'] = function() + builtin_cli({}, { source = { name = 'My name' } }) + validate_picker_option('source.name', 'My name') +end + +T['builtin.resume()'] = new_set() + +local builtin_resume = forward_lua_notify('MiniPick.builtin.resume') + +T['builtin.resume()']['works'] = function() + local items = { 'a', 'b', 'bb' } + start_with_items(items) + type_keys('b') + eq(get_picker_matches().all, { 'b', 'bb' }) + type_keys('') + + make_event_log() + child.cmd('au User MiniPickStart lua _G.track_event()') + + child.lua_notify('_G.resume_item = MiniPick.builtin.resume()') + + -- User event should be triggered when all elements are usually set + eq(child.lua_get('_G.event_log'), { 2 }) + + -- Should preserve as much as state as possible from latest picker + child.expect_screenshot() + eq(get_picker_items(), items) + eq(get_picker_matches().all, { 'b', 'bb' }) + eq(get_picker_query(), { 'b' }) + + type_keys('') + eq(get_picker_matches().all, items) + type_keys('a') + eq(get_picker_matches().all, { 'a' }) + + -- Should return value + type_keys('') + eq(child.lua_get('_G.resume_item'), 'a') +end + +T['builtin.resume()']['can be called after previous picker was aborted'] = function() + start_with_items({ 'aa', 'bb' }) + type_keys('a', '') + + builtin_resume() + eq(get_picker_query(), { 'a' }) + eq(get_picker_matches().all, { 'aa' }) + eq(get_picker_items(), { 'aa', 'bb' }) +end + +T['builtin.resume()']['always starts in main view'] = function() + start_with_items({ 'a' }) + type_keys('') + validate_picker_view('preview') + type_keys('') + + builtin_resume() + validate_picker_view('main') + + type_keys('') + validate_picker_view('info') + type_keys('') + + builtin_resume() + validate_picker_view('main') +end + +T['builtin.resume()']['preserves current working directory'] = function() + local dir_1, dir_2 = full_path(test_dir), full_path(real_files_dir) + child.fn.chdir(dir_1) + start_with_items({ 'a' }) + validate_picker_option('source.cwd', full_path(dir_1)) + type_keys('') + + child.fn.chdir(dir_2) + builtin_resume() + validate_picker_option('source.cwd', full_path(dir_1)) +end + +T['builtin.resume()']['preserves query cache'] = function() + local validate_match_calls = make_match_with_count() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'bb' }, match = _G.match_with_count }, + options = { use_cache = true }, + })]]) + validate_match_calls(0, { 1, 2, 3 }) + + type_keys('b') + validate_match_calls(1, { 2, 3 }) + + type_keys('b') + validate_match_calls(2, { 3 }) + + -- Close and resume + type_keys('') + builtin_resume() + validate_match_calls(2, { 3 }) + + type_keys('') + validate_match_calls(2, { 2, 3 }) + + type_keys('') + validate_match_calls(2, { 1, 2, 3 }) +end + +T['builtin.resume()']['preserves marked items'] = function() + start_with_items({ 'aa', 'bb' }) + type_keys('', '') + + builtin_resume() + eq(get_picker_matches().marked_inds, { 1 }) +end + +T['builtin.resume()']['recomputes target window'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + + start_with_items({ 'a' }) + eq(get_picker_state().windows.target, win_id_1) + type_keys('') + + child.api.nvim_set_current_win(win_id_2) + builtin_resume() + eq(get_picker_state().windows.target, win_id_2) +end + +T['builtin.resume()']['can be called consecutively'] = function() + local validate = function(query, matches, items) + eq(get_picker_query(), query) + eq(get_picker_matches().all, matches) + eq(get_picker_items(), items) + end + + start_with_items({ 'aa', 'bb' }) + type_keys('a') + validate({ 'a' }, { 'aa' }, { 'aa', 'bb' }) + type_keys('') + + builtin_resume() + type_keys('', 'b') + validate({ 'b' }, { 'bb' }, { 'aa', 'bb' }) + type_keys('') + + builtin_resume() + type_keys('b') + validate({ 'b', 'b' }, { 'bb' }, { 'aa', 'bb' }) + type_keys('') +end + +T['builtin.resume()']['validates if no picker was previously called'] = function() + expect.error(function() child.lua('MiniPick.builtin.resume()') end, 'no picker to resume') +end + +T['registry'] = new_set() + +T['registry']['works'] = function() + eq(child.lua_get('type(MiniPick.registry)'), 'table') + + -- All methods from `builtin` should be present + local builtin_methods = child.lua_get('vim.tbl_keys(MiniPick.builtin)') + table.sort(builtin_methods) + local registry_methods = child.lua_get('vim.tbl_keys(MiniPick.registry)') + table.sort(registry_methods) + eq(builtin_methods, registry_methods) + + local actual_types = child.lua_get('vim.tbl_map(type, MiniPick.registry)') + local ref_types = {} + for _, key in ipairs(builtin_methods) do + ref_types[key] = 'function' + end + eq(actual_types, ref_types) +end + +T['registry']['should contain values from `MiniExtra.pickers` if present'] = function() + unload_module() + child.lua([[package.loaded['mini.pick'] = nil]]) + + child.lua('_G.MiniExtra = { pickers = { miniextra_method = function() end } }') + load_module() + eq(child.lua_get('type(MiniPick.registry.miniextra_method)'), 'function') +end + +T['registry']['is not reloaded in `setup()`'] = function() + child.lua([[MiniPick.registry.custom = function() end]]) + child.lua([[require('mini.pick').setup()]]) + eq(child.lua_get('type(MiniPick.registry.custom)'), 'function') +end + +T['get_picker_items()'] = new_set() + +T['get_picker_items()']['works'] = function() + local items = { 'aa', { text = 'bb' } } + start_with_items(items) + child.lua('_G.res = MiniPick.get_picker_items()') + eq(child.lua_get('_G.res'), items) + + -- Returns copy + child.lua([[_G.res[2].text = 'xx']]) + eq(child.lua_get('MiniPick.get_picker_items()'), items) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(get_picker_items(), vim.NIL) +end + +T['get_picker_items()']['handles callables'] = function() + -- Should return actual `items` after global callable expansion + child.lua_notify([[MiniPick.start({ source = { items = function() return { 'aa' } end } })]]) + eq(get_picker_items(), { 'aa' }) + type_keys('') + + -- Should not expand callable item + child.lua_notify([[MiniPick.start({ source = { items = { function() return 'aa' end } } })]]) + eq(child.lua_get('type(MiniPick.get_picker_items()[1])'), 'function') +end + +T['get_picker_stritems()'] = new_set() + +T['get_picker_stritems()']['works'] = function() + local items, stritems = { 'aa', { text = 'bb' } }, { 'aa', 'bb' } + start_with_items(items) + child.lua('_G.res = MiniPick.get_picker_stritems()') + eq(child.lua_get('_G.res'), stritems) + + -- Returns copy + child.lua([[_G.res[2] = 'xx']]) + eq(child.lua_get('MiniPick.get_picker_stritems()'), stritems) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(get_picker_stritems(), vim.NIL) +end + +T['get_picker_stritems()']['handles callables'] = function() + -- Should always return array of strings + child.lua_notify([[MiniPick.start({ source = { items = function() return { 'aa' } end } })]]) + eq(get_picker_stritems(), { 'aa' }) + type_keys('') + + child.lua_notify([[MiniPick.start({ source = { items = { function() return 'aa' end } } })]]) + eq(get_picker_stritems(), { 'aa' }) +end + +T['get_picker_stritems()']["ignores 'ignorecase'"] = function() + child.o.ignorecase = true + start_with_items({ 'ab', 'Ab', 'AB' }) + eq(get_picker_stritems(), { 'ab', 'Ab', 'AB' }) +end + +T['get_picker_matches()'] = new_set() + +T['get_picker_matches()']['works'] = function() + local items = { { text = 'aa' }, 'bb', 'cc' } + start_with_items(items) + child.lua('_G.res = MiniPick.get_picker_matches()') + + local ref = + { all = items, all_inds = { 1, 2, 3 }, current = items[1], current_ind = 1, marked = {}, marked_inds = {} } + eq(child.lua_get('_G.res'), ref) + + -- Returns copy + child.lua([[_G.res.all[1], _G.res.all_inds[1] = 'xx', 100]]) + child.lua([[_G.res.current, _G.res.current_ind = 'yy', 200]]) + child.lua([[_G.res.marked[1], _G.res.marked_inds[1] = 'tt', 300]]) + eq(get_picker_matches(), ref) +end + +T['get_picker_matches()']['reacts to change in all matches'] = function() + local validate = function(ref_all, ref_all_inds) + local matches = get_picker_matches() + eq(matches.all, ref_all) + eq(matches.all_inds, ref_all_inds) + end + + local items = { 'a', 'bb', 'b' } + start_with_items(items) + validate(items, { 1, 2, 3 }) + + type_keys('b') + validate({ 'bb', 'b' }, { 2, 3 }) + + type_keys('b') + validate({ 'bb' }, { 2 }) + + type_keys('x') + validate({}, {}) +end + +T['get_picker_matches()']['reacts to change in current match'] = function() + local validate = function(ref_current, ref_current_ind) + local matches = get_picker_matches() + eq(matches.current, ref_current) + eq(matches.current_ind, ref_current_ind) + end + + local items = { 'a', 'b', 'c' } + start_with_items(items) + validate(items[1], 1) + + type_keys('') + validate(items[2], 2) + + type_keys('') + validate(items[1], 1) +end + +T['get_picker_matches()']['reacts to change in marked matches'] = function() + local validate = function(ref_marked, ref_marked_inds) + local matches = get_picker_matches() + eq(matches.marked, ref_marked) + eq(matches.marked_inds, ref_marked_inds) + end + + local items = { 'a', 'b', 'c' } + start_with_items(items) + validate({}, {}) + + type_keys('') + validate({ items[1] }, { 1 }) + + type_keys('', '', '') + validate({ items[1], items[3] }, { 1, 3 }) +end + +T['get_picker_matches()']['handles no matches'] = function() + -- When no active picker + eq(get_picker_matches(), vim.NIL) + + -- When no items are set + start_with_items() + eq(get_picker_items(), vim.NIL) + eq(get_picker_matches(), {}) + + -- When `items` is empty table + set_picker_items({}) + eq(get_picker_items(), {}) + eq(get_picker_matches(), {}) +end + +T['get_picker_opts()'] = new_set() + +T['get_picker_opts()']['works'] = function() + child.lua('MiniPick.config.window.config = { col = 2 }') + child.lua('_G.choose = function(item) print(item) end') + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'b' }, name = 'My name', choose = _G.choose } })]]) + + child.lua([[_G.res = MiniPick.get_picker_opts()]]) + + local validate_as_config = function(field) + local lua_cmd = string.format('vim.deep_equal(_G.res.%s, MiniPick.config.%s)', field, field) + eq(child.lua_get(lua_cmd), true) + end + + validate_as_config('delay') + validate_as_config('mappings') + validate_as_config('options') + validate_as_config('config') + + -- - Not supplied `source` callables chould be inferred + eq(child.lua_get('_G.res.source.items'), { 'a', 'b' }) + eq(child.lua_get('_G.res.source.name'), 'My name') + eq(child.lua_get('_G.res.source.cwd'), full_path(child.fn.getcwd())) + + eq(child.lua_get('_G.res.source.match == MiniPick.default_match'), true) + eq(child.lua_get('_G.res.source.show == MiniPick.default_show'), true) + eq(child.lua_get('_G.res.source.preview == MiniPick.default_preview'), true) + eq(child.lua_get('_G.res.source.choose == _G.choose'), true) + eq(child.lua_get('_G.res.source.choose_marked == MiniPick.default_choose_marked'), true) + + -- Returns copy + child.lua([[_G.res.delay.busy, _G.res.source.name = -10, 'Hello']]) + child.lua('_G.opts_2 = MiniPick.get_picker_opts()') + eq(child.lua_get('_G.opts_2.delay.busy == MiniPick.config.delay.busy'), true) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(child.lua_get('MiniPick.get_picker_opts()'), vim.NIL) +end + +T['get_picker_state()'] = new_set() + +T['get_picker_state()']['works'] = function() + local items = { { text = 'aa' }, 'bb', 'cc' } + start_with_items(items) + child.lua('_G.res = MiniPick.get_picker_state()') + local res = child.lua_get('_G.res') + + eq(child.api.nvim_buf_is_valid(res.buffers.main), true) + eq(child.api.nvim_win_is_valid(res.windows.main), true) + eq(child.api.nvim_win_is_valid(res.windows.target), true) + eq(res.caret, 1) + eq(res.is_busy, false) + + -- Returns copy + child.lua([[_G.res.buffers.main, _G.res.windows.main = -100, -101]]) + local state = get_picker_state() + eq(child.api.nvim_buf_is_valid(state.buffers.main), true) + eq(child.api.nvim_win_is_valid(state.windows.main), true) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(get_picker_state(), vim.NIL) +end + +T['get_picker_state()']['reacts to creation of preview and info views'] = function() + local validate = function(ref) + local actual = vim.tbl_map(function(x) + if x == nil then return nil end + return child.api.nvim_buf_is_valid(x) + end, get_picker_state().buffers) + eq(actual, ref) + end + + start_with_items({ 'a', 'b', 'c' }) + validate({ main = true, preview = nil, info = nil }) + + type_keys('') + validate({ main = true, preview = true, info = nil }) + + type_keys('') + -- - Preview buffers have 'bufhidden' set to 'wipe', so become not valid + validate({ main = true, preview = false, info = true }) + + type_keys('') + -- - Info buffers are persistent during picker session + validate({ main = true, preview = true, info = true }) +end + +T['get_picker_state()']['reacts to change in target window'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + + start_with_items() + eq(get_picker_state().windows.target, win_id_1) + + child.lua(string.format('MiniPick.set_picker_target_window(%d)', win_id_2)) + eq(get_picker_state().windows.target, win_id_2) +end + +T['get_picker_state()']['properly detects when picker is busy'] = function() + child.lua([[_G.match_defer = function() + local f = function() + local co = coroutine.running() + vim.defer_fn(function() coroutine.resume(co) end, 10) + coroutine.yield() + + MiniPick.set_picker_match_inds({ 1 }) + end + + coroutine.resume(coroutine.create(f)) + end]]) + child.lua_notify('MiniPick.start({ source = { match = match_defer } })') + + -- Between starting picker and first setting items + eq(get_picker_state().is_busy, true) + set_picker_items({ 'a', 'b' }, { do_match = false }) + eq(get_picker_state().is_busy, false) + + -- Between starting match and displaying its results + type_keys('a') + eq(get_picker_state().is_busy, true) + sleep(10 + 10) + eq(get_picker_state().is_busy, false) +end + +T['get_picker_state()']['reacts to caret update'] = function() + start_with_items({ 'a', 'b', 'bb' }) + eq(get_picker_state().caret, 1) + + type_keys('abc') + eq(get_picker_state().caret, 4) + + type_keys('') + eq(get_picker_state().caret, 3) + + type_keys('') + eq(get_picker_state().caret, 2) +end + +T['get_picker_query()'] = new_set() + +T['get_picker_query()']['works'] = function() + start_with_items() + child.lua('_G.res = MiniPick.get_picker_query()') + eq(child.lua_get('_G.res'), {}) + + -- Returns copy + child.lua([[_G.res[1] = 'a']]) + eq(get_picker_query(), {}) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(get_picker_query(), vim.NIL) +end + +T['get_picker_query()']['reacts to query update'] = function() + local items = { 'a', 'b', 'bb' } + start_with_items(items) + + -- Manual + eq(get_picker_query(), {}) + type_keys('b') + eq(get_picker_query(), { 'b' }) + type_keys('b') + eq(get_picker_query(), { 'b', 'b' }) + type_keys('b') + eq(get_picker_query(), { 'b', 'b', 'b' }) + type_keys('') + eq(get_picker_query(), { 'b', 'b' }) + type_keys('') + eq(get_picker_query(), {}) + + -- Programmatic + set_picker_query({ 'aa', 'bb' }) + eq(get_picker_query(), { 'aa', 'bb' }) +end + +T['set_picker_items()'] = new_set() + +local set_picker_items = forward_lua('MiniPick.set_picker_items') + +T['set_picker_items()']['works'] = function() + start_with_items() + set_picker_items({ 'a', 'b' }) + eq(get_picker_items(), { 'a', 'b' }) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(get_picker_query(), vim.NIL) +end + +T['set_picker_items()']['resets match inds prior to matching'] = function() + start_with_items({ 'a', 'b', 'bb' }) + type_keys('b') + eq(get_picker_matches().all_inds, { 2, 3 }) + + set_picker_items({ 'b', 'bb', 'a' }) + eq(get_picker_matches().all_inds, { 1, 2 }) +end + +T['set_picker_items()']['resets marked inds'] = function() + start_with_items({ 'a', 'b', 'bb' }) + type_keys('', '', '') + eq(get_picker_matches().marked_inds, { 1, 2 }) + + set_picker_items({ 'a', 'b', 'bb' }) + eq(get_picker_matches().marked_inds, {}) +end + +T['set_picker_items()']['resets query cache'] = function() + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'b' } }, options = { use_cache = true } })]]) + type_keys('a') + eq(get_picker_matches().all_inds, { 1 }) + type_keys('') + + set_picker_items({ 'x', 'a', 'aa' }) + type_keys('a') + eq(get_picker_matches().all_inds, { 2, 3 }) +end + +T['set_picker_items()']['respects `opts.do_match`'] = function() + local validate_match_calls = make_match_with_count() + child.lua_notify([[MiniPick.start({ source = { match = _G.match_with_count } })]]) + validate_match_calls(0, nil) + + set_picker_items({ 'a', 'b' }, { do_match = false }) + validate_match_calls(0, { 1, 2 }) + + type_keys('a') + validate_match_calls(1, { 1 }) + + set_picker_items({ 'aa', 'bb' }, { do_match = false }) + validate_match_calls(1, { 1, 2 }) +end + +T['set_picker_items()']['respects `opts.querytick`'] = function() + -- Should check every `delay.async` milliseconds if global querytick is the + -- same as supplied. If not - abort without setting items. + child.lua('MiniPick.config.delay.async = 1') + + start_with_items() + set_picker_items(many_items, { querytick = -1 }) + eq(get_picker_items(), vim.NIL) +end + +T['set_picker_items()']['does not block picker'] = function() + child.lua([[ + _G.log = {} + _G.log_func = function() + local entry = { is_busy = MiniPick.get_picker_state().is_busy, items_type = type(MiniPick.get_picker_items()) } + table.insert(_G.log, entry) + end + _G.mappings = { append_log = { char = 'l', func = _G.log_func } } + ]]) + child.lua_notify('MiniPick.start({ mappings = _G.mappings, delay = { async = 1 } })') + + -- Set many items and start typing right away. Key presses should be + -- processed right away even though there is an items preprocessing is going. + set_picker_items(many_items) + type_keys('l') + sleep(1) + stop() + eq(child.lua_get('_G.log'), { { is_busy = true, items_type = 'nil' } }) +end + +T['set_picker_items()']['validates arguments'] = function() + start_with_items() + expect.error(function() set_picker_items(1) end, '`items`.*array') +end + +T['set_picker_items_from_cli()'] = new_set({ hooks = { pre_case = mock_spawn } }) + +local set_picker_items_from_cli = function(...) + -- Work around tuples and callables being not transferrable through RPC + local tuple = child.lua( + [[local process, pid = MiniPick.set_picker_items_from_cli(...) + local process_keys = vim.tbl_keys(process) + table.sort(process_keys) + return { process_keys, pid }]], + { ... } + ) + return unpack(tuple) +end + +local test_command = { 'echo', 'a\nb\nc' } + +T['set_picker_items_from_cli()']['works'] = function() + start_with_items() + mock_stdout_feed({ 'abc\ndef\n', 'ghi' }) + local process_keys, pid = set_picker_items_from_cli({ 'command', 'arg1', 'arg2' }) + + -- Should actually set picker items + eq(get_picker_items(), { 'abc', 'def', 'ghi' }) + + -- Should properly call `vim.spawn` + validate_spawn_log({ { executable = 'command', options = { args = { 'arg1', 'arg2' } } } }) + + -- Should properly handle process and stdout + eq(get_process_log(), { 'Stdout Stdout_1 was closed.', 'Process Pid_1 was closed.' }) + + -- Should return proper data + eq(process_keys, { 'close', 'pid' }) + eq(pid, 'Pid_1') +end + +T['set_picker_items_from_cli()']['can override items'] = function() + start_with_items({ 'a', 'b', 'c' }) + mock_stdout_feed({ 'd\ne\nf' }) + set_picker_items_from_cli({ 'echo' }) + eq(get_picker_items(), { 'd', 'e', 'f' }) +end + +T['set_picker_items_from_cli()']['can be called without active picker'] = function() + expect.no_error(function() + local output = child.lua_get([[MiniPick.set_picker_items_from_cli({ 'echo', '1\n2\n' }, {})]]) + eq(output, vim.NIL) + end) +end + +T['set_picker_items_from_cli()']['correctly processes stdout feed'] = function() + -- Should stich items together without adding '\n' + start_with_items() + mock_stdout_feed({ 'aa\n', 'bb', 'cc\n', 'dd', '\nee' }) + set_picker_items_from_cli(test_command) + eq(get_picker_items(), { 'aa', 'bbcc', 'dd', 'ee' }) +end + +T['set_picker_items_from_cli()']['correctly detects error in stdout feed'] = function() + start_with_items() + mock_stdout_feed({ 'aa\n', 'bb', { err = 'Test stdout error' } }) + expect.error(function() set_picker_items_from_cli(test_command) end, 'Test stdout error') +end + +T['set_picker_items_from_cli()']['has default postprocess'] = function() + -- Should remove all trailing empty lines + start_with_items() + mock_stdout_feed({ 'aa\nbb \n \n\t\n\n\n' }) + set_picker_items_from_cli(test_command) + eq(get_picker_items(), { 'aa', 'bb ', ' ', '\t' }) +end + +T['set_picker_items_from_cli()']['respects `opts.postprocess`'] = function() + start_with_items() + mock_stdout_feed({ 'aa\nbb\n' }) + child.lua([[MiniPick.set_picker_items_from_cli( + { 'echo', 'aa\nbb' }, + { postprocess = function(lines) + _G.postprocess_input = lines + -- Should be possible to call `vim.fn` functions inside of it + local n_chars = vim.fn.strchars(lines[1]) + -- Can return any number of items + return { 'item 1', 'item 2', 'item 3', 'item 4' } + end + } + )]]) + eq(get_picker_items(), { 'item 1', 'item 2', 'item 3', 'item 4' }) + eq(child.lua_get('_G.postprocess_input'), { 'aa', 'bb', '' }) +end + +T['set_picker_items_from_cli()']['respects `opts.set_item_opts`'] = function() + child.lua('MiniPick.set_picker_items = function(...) _G.args = { ... } end') + start_with_items() + mock_stdout_feed({ 'aa\nbb' }) + set_picker_items_from_cli(test_command, { set_items_opts = { custom_option = true } }) + eq(child.lua_get('_G.args'), { { 'aa', 'bb' }, { custom_option = true } }) +end + +T['set_picker_items_from_cli()']['respects `opts.spawn_opts`'] = function() + start_with_items() + set_picker_items_from_cli({ 'echo', 'arg1', 'arg2' }, { spawn_opts = { env = { HELLO = 'WORLD' } } }) + validate_spawn_log({ + executable = 'echo', + options = { args = { 'arg1', 'arg2' }, env = { HELLO = 'WORLD' } }, + }, 1) +end + +T['set_picker_items_from_cli()']['forces absolute path of `opts.spawn_opts.cwd`'] = function() + start_with_items() + set_picker_items_from_cli({ 'echo', 'arg' }, { spawn_opts = { cwd = 'tests' } }) + validate_spawn_log({ + executable = 'echo', + options = { args = { 'arg' }, cwd = full_path('tests') }, + }, 1) +end + +T['set_picker_items_from_cli()']['validates arguments'] = function() + start_with_items() + expect.error(function() set_picker_items_from_cli(1) end, '`command`.*array of strings') + expect.error(function() set_picker_items_from_cli({}) end, '`command`.*array of strings') + expect.error(function() set_picker_items_from_cli({ 'a', 2, 'c' }) end, '`command`.*array of strings') +end + +T['set_picker_match_inds()'] = new_set() + +local set_picker_match_inds = forward_lua('MiniPick.set_picker_match_inds') + +T['set_picker_match_inds()']['works'] = function() + child.lua_notify([[MiniPick.start({ + source = { + items = { 'a', 'b', 'bb' }, + match = function() MiniPick.set_picker_match_inds({ 2 }) end, + }, + })]]) + child.expect_screenshot() + eq(get_picker_matches().all_inds, { 2 }) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(set_picker_match_inds({ 1 }), vim.NIL) +end + +T['set_picker_match_inds()']['updates cache'] = function() + local validate_match_calls = make_match_with_count() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'bb' }, match = _G.match_with_count }, + options = { use_cache = true }, + })]]) + validate_match_calls(0, { 1, 2, 3 }) + + type_keys('a') + validate_match_calls(1, { 1 }) + + -- - Setting match inds should not trigger `source.match` + set_picker_match_inds({ 2, 3 }) + validate_match_calls(1, { 2, 3 }) + + type_keys('') + validate_match_calls(1, { 1, 2, 3 }) + + type_keys('a') + validate_match_calls(1, { 2, 3 }) +end + +T['set_picker_match_inds()']['sets first index as current'] = function() + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'b', 'bb' }, match = function() end } })]]) + + type_keys('', '') + validate_current_ind(3) + + set_picker_match_inds({ 2, 3 }) + validate_current_ind(2) +end + +T['set_picker_match_inds()']['validates arguments'] = function() + start_with_items() + expect.error(function() set_picker_match_inds(1) end, '`match_inds`.*array') + expect.error(function() set_picker_match_inds({ 'a' }) end, '`match_inds`.*numbers') +end + +T['set_picker_opts()'] = new_set() + +T['set_picker_opts()']['works'] = function() + local expect_screenshot = function() + if child.has_float_footer() then child.expect_screenshot_orig() end + end + + start_with_items({ 'a', 'b', 'bb' }) + expect_screenshot() + + child.lua([[MiniPick.set_picker_opts({ source = { name = 'My name' }, window = { config = { col = 5 } } })]]) + expect_screenshot() + + -- Should rerun match + child.lua('MiniPick.set_picker_opts({ source = { match = function() return { 2 } end } })') + eq(get_picker_matches().all_inds, { 2 }) + expect_screenshot() + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(child.lua([[MiniPick.set_picker_opts({ source = { name = 'New name' } })]]), vim.NIL) +end + +T['set_picker_target_window()'] = new_set() + +T['set_picker_target_window()']['works'] = function() + local win_id_1, win_id_2 = setup_windows_pair() + local path = real_file('b.txt') + start_with_items({ path }) + child.lua(string.format('MiniPick.set_picker_target_window(%d)', win_id_2)) + type_keys('') + + validate_buf_name(child.api.nvim_win_get_buf(win_id_1), '') + validate_buf_name(child.api.nvim_win_get_buf(win_id_2), path) + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + local lua_cmd = string.format('MiniPick.set_picker_target_window(%d)', win_id_2) + eq(child.lua_get(lua_cmd), vim.NIL) +end + +T['set_picker_target_window()']['validates arguments'] = function() + start_with_items() + expect.error(function() child.lua('MiniPick.set_picker_target_window(-1)') end, '`win_id`.*not a valid window') +end + +T['set_picker_query()'] = new_set() + +T['set_picker_query()']['works'] = function() + start_with_items({ 'a', 'b', 'bb' }) + + -- Should update querytick + local querytick = get_querytick() + set_picker_query({ 'b', 'b' }) + eq(get_querytick(), querytick + 1) + + -- Should match and update visual feedback + child.expect_screenshot() + + -- Can be called without active picker + type_keys('') + eq(is_picker_active(), false) + eq(set_picker_query({ 'a' }), vim.NIL) +end + +T['set_picker_query()']['resets caret'] = function() + start_with_items({ 'a', 'b', 'bb' }) + type_keys('b', 'b', '') + eq(get_picker_state().caret, 2) + + set_picker_query({ 'x', 'x', 'x', 'x' }) + eq(get_picker_state().caret, 5) + + set_picker_query({ 'x' }) + eq(get_picker_state().caret, 2) +end + +T['set_picker_query()']['respects cache'] = function() + local validate_match_calls = make_match_with_count() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'bb' }, match = _G.match_with_count }, + options = { use_cache = true }, + })]]) + validate_match_calls(0, { 1, 2, 3 }) + + -- Should update it + set_picker_query({ 'b' }) + validate_match_calls(1, { 2, 3 }) + + type_keys('', 'b') + validate_match_calls(1, { 2, 3 }) + + -- Should use it + type_keys('') + set_picker_query({ 'b' }) + validate_match_calls(1, { 2, 3 }) +end + +T['set_picker_query()']['resets match inds prior to matching'] = function() + start_with_items({ 'a', 'b', 'bb' }) + type_keys('b') + eq(get_picker_matches().all_inds, { 2, 3 }) + + set_picker_query({ 'a' }) + eq(get_picker_matches().all_inds, { 1 }) +end + +T['set_picker_query()']['validates arguments'] = function() + start_with_items() + expect.error(function() set_picker_query(1) end, '`query`.*array') + expect.error(function() set_picker_query({ 1 }) end, '`query`.*strings') +end + +T['get_querytick()'] = new_set() + +local get_querytick = forward_lua('MiniPick.get_querytick') + +T['get_querytick()']['works'] = function() + local init_querytick = get_querytick() + eq(type(init_querytick), 'number') + + local validate = function(increase) eq(get_querytick(), init_querytick + increase) end + + -- Should increase after start, any query update, and stop, but not on move + -- - Start + start_with_items({ 'a', 'b', 'bb' }) + validate(1) + + -- - Query update + type_keys('a') + validate(2) + + type_keys('') + validate(3) + + set_picker_query({ 'a', 'b' }) + validate(4) + + type_keys('') + validate(5) + + -- - Move + type_keys('') + validate(5) + + type_keys('') + validate(5) + + type_keys('') + validate(5) + + type_keys('') + validate(5) + + -- - Change view + type_keys('') + validate(5) + + type_keys('') + validate(5) + + -- - Stop + type_keys('') + validate(6) +end + +T['get_querytick()']['updates even with enabled cache'] = function() + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'b' } }, options = { use_cache = true } })]]) + local init_querytick = get_querytick() + + type_keys('a') + eq(get_querytick(), init_querytick + 1) + + type_keys('') + eq(get_querytick(), init_querytick + 2) + + type_keys('a') + eq(get_querytick(), init_querytick + 3) +end + +T['is_picker_active()'] = new_set() + +T['is_picker_active()']['works'] = function() + eq(is_picker_active(), false) + start_with_items() + eq(is_picker_active(), true) + type_keys('') + eq(is_picker_active(), false) +end + +T['poke_is_picker_active()'] = new_set() + +local poke_is_picker_active = forward_lua('MiniPick.poke_is_picker_active') + +T['poke_is_picker_active()']['works without running coroutine'] = function() + eq(poke_is_picker_active(), false) + start_with_items() + eq(poke_is_picker_active(), true) + type_keys('') + eq(poke_is_picker_active(), false) +end + +T['poke_is_picker_active()']['works with running coroutine'] = function() + start_with_items() + eq(poke_is_picker_active(), true) + + child.lua([[ + -- Poke on next event loop + local f = function() _G.is_active_poke = MiniPick.poke_is_picker_active() end + coroutine.resume(coroutine.create(f)) + _G.is_active_direct = MiniPick.is_picker_active() + + -- Dedect no poking before + _G.has_not_poked_yet = _G.is_active_poke == nil + ]]) + eq(child.lua_get('_G.is_active_direct'), true) + eq(child.lua_get('_G.has_not_poked_yet'), true) + eq(child.lua_get('_G.is_active_poke'), true) +end + +-- Integration tests ========================================================== +T[':Pick'] = new_set() + +T[':Pick']['works'] = function() + mock_opened_buffers() + + local validate = function(args) + child.api_notify.nvim_exec('Pick ' .. args, false) + eq(is_picker_active(), true) + child.expect_screenshot() + type_keys('') + end + + validate('buffers') + validate('buffers include_unlisted=true') +end + +T[':Pick']['correctly parses arguments'] = function() + child.lua('MiniPick.registry.aaa = function(...) _G.args = { ... } end') + + child.cmd([[Pick aaa b='b' c=3 d={x=1,\ y=2}]]) + eq(child.lua_get('_G.args'), { { b = 'b', c = 3, d = { x = 1, y = 2 } } }) + + -- Expands arguments + child.cmd('edit ' .. real_file('b.txt')) + child.cmd([[Pick aaa basename='%:t' extension='%:e']]) + eq(child.lua_get('_G.args'), { { basename = 'b.txt', extension = 'txt' } }) + + -- Throws informative error (here because of not escaped whitespace) + expect.error(function() child.cmd([[Pick aaa t={ a = 1}]]) end, 'Could not convert.*to table.*t={,') +end + +T[':Pick']['has proper complete'] = function() + child.set_size(10, 20) + local validate = function(keys) + type_keys(':Pick ', keys, '') + child.expect_screenshot() + type_keys('') + end + + validate({}) + validate({ 'f' }) + validate({ 'f x', '', '' }) +end + +T[':Pick']['validates arguments'] = function() + expect.error(function() child.cmd('Pick aaa') end, 'no picker named "aaa"') +end + +T['Overall view'] = new_set() + +T['Overall view']['shows prompt'] = function() + child.set_size(10, 20) + start_with_items() + + -- Initial + child.expect_screenshot() + + -- After typical typing + type_keys('a') + child.expect_screenshot() + type_keys(' b') + child.expect_screenshot() + + -- After moving caret + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() +end + +T['Overall view']['uses footer for extra info'] = function() + if not child.has_float_footer() then return end + + start_with_items({ 'a', 'b', 'bb', 'bbb' }, 'My name') + child.expect_screenshot_orig() + + -- Should update after matching + type_keys('b') + child.expect_screenshot_orig() + + -- Should update after moving + type_keys('') + child.expect_screenshot_orig() + + -- Should update after marking and unmarking + type_keys('') + child.expect_screenshot_orig() + type_keys('') + child.expect_screenshot_orig() + + -- Should correctly show no matches + type_keys('x') + child.expect_screenshot_orig() +end + +T['Overall view']['correctly infers footer empty space'] = function() + if not child.has_float_footer() then return end + + local validate = function(win_config) + local lua_cmd = string.format('MiniPick.config.window.config = %s', vim.inspect(win_config)) + child.lua(lua_cmd) + start_with_items({ 'a' }) + child.expect_screenshot_orig() + type_keys('') + end + + -- Check both `border = 'double'` and `border = ` + validate({ border = 'double' }) + validate({ border = { '!', '@', '#', '$', '%', '^', '&', '*' } }) +end + +T['Overall view']['does not show footer if items are not set'] = function() + if not child.has_float_footer() then return end + start_with_items() + child.expect_screenshot_orig() +end + +T['Overall view']['respects `options.content_from_bottom` with footer'] = function() + if not child.has_float_footer() then return end + + start({ source = { items = { 'a', 'b' } }, options = { content_from_bottom = true } }) + child.expect_screenshot_orig() +end + +T['Overall view']['truncates border text'] = function() + if not child.has_float_footer() then return end + + local validate = function(...) + child.set_size(...) + start_with_items({ 'a' }, 'Very long name') + set_picker_query({ 'very long query' }) + child.expect_screenshot_orig() + type_keys('') + end + + validate(10, 20) + -- Should not partially show footer indexes, only in full (when space allows) + validate(10, 35) +end + +T['Overall view']['allows "none" as border'] = function() + if not child.has_float_footer() then return end + + child.lua([[MiniPick.config.window.config = { border = 'none' }]]) + start_with_items({ 'a' }, 'My name') + child.expect_screenshot_orig() +end + +T['Overall view']["respects tabline, statusline, 'cmdheight'"] = function() + local validate = function() + start_with_items({ 'a' }, 'My name') + child.expect_screenshot() + type_keys('') + end + + child.set_size(10, 20) + + child.o.showtabline, child.o.laststatus = 2, 2 + validate() + + child.o.showtabline, child.o.laststatus = 2, 0 + validate() + + child.o.showtabline, child.o.laststatus = 0, 2 + validate() + + child.o.showtabline, child.o.laststatus = 0, 0 + validate() + + if child.fn.has('nvim-0.8') == 0 then return end + child.o.cmdheight = 0 + validate() + + child.o.cmdheight = 3 + validate() +end + +T['Overall view']['allows very large dimensions'] = function() + child.lua('MiniPick.config.window.config = { height = 100, width = 200 }') + start_with_items({ 'a' }, 'My name') + child.expect_screenshot() +end + +T['Overall view']['uses dedicated highlight groups'] = function() + start_with_items(nil, 'My name') + local win_id = get_picker_state().windows.main + sleep(child.lua_get('MiniPick.config.delay.busy') + 5) + + -- Busy picker + eq(get_picker_state().is_busy, true) + + local winhighlight = child.api.nvim_win_get_option(win_id, 'winhighlight') + expect.match(winhighlight, 'NormalFloat:MiniPickNormal') + expect.match(winhighlight, 'FloatBorder:MiniPickBorderBusy') + + local win_config = child.api.nvim_win_get_config(win_id) + if child.fn.has('nvim-0.9') == 1 then eq(win_config.title, { { '> ▏', 'MiniPickPrompt' } }) end + + -- Not busy picker + set_picker_items({ 'a' }) + eq(get_picker_state().is_busy, false) + + winhighlight = child.api.nvim_win_get_option(win_id, 'winhighlight') + expect.match(winhighlight, 'FloatBorder:MiniPickBorder') + + if child.has_float_footer() then + win_config = child.api.nvim_win_get_config(win_id) + local footer = win_config.footer + eq(footer[1], { ' My name ', 'MiniPickBorderText' }) + eq(footer[2][2], 'MiniPickBorder') + eq(footer[3], { ' 1|1|1 ', 'MiniPickBorderText' }) + end +end + +T['Overall view']['is shown over number and sign columns'] = function() + child.set_size(10, 20) + child.o.number, child.o.signcolumn = true, 'yes' + child.api.nvim_buf_set_lines(0, 0, -1, false, { 'a', 'b', 'c', 'd', 'e' }) + start_with_items({ 'a' }) + child.expect_screenshot() +end + +T['Main view'] = new_set() + +T['Main view']['uses dedicated highlight groups'] = function() + local validate_extmark = + function(extmark_data, line, hl_group) eq({ extmark_data[2], extmark_data[4].hl_group }, { line - 1, hl_group }) end + + child.lua([[MiniPick.config.source.show = function(buf_id, items, query) + return MiniPick.default_show(buf_id, items, query, { show_icons = true }) + end]]) + start_with_items({ real_file('b.txt'), test_dir, 'marked', 'current' }) + local buf_id = get_picker_state().buffers.main + type_keys('', '', '', '') + + local match_ns_id = child.api.nvim_get_namespaces().MiniPickMatches + local match_extmarks = child.api.nvim_buf_get_extmarks(buf_id, match_ns_id, 0, -1, { details = true }) + validate_extmark(match_extmarks[1], 3, 'MiniPickMatchMarked') + validate_extmark(match_extmarks[2], 4, 'MiniPickMatchCurrent') + + type_keys('d', 'i', 'r') + + local ranges_ns_id = child.api.nvim_get_namespaces().MiniPickRanges + local ranges_extmarks = child.api.nvim_buf_get_extmarks(buf_id, ranges_ns_id, 0, -1, { details = true }) + validate_extmark(ranges_extmarks[1], 1, 'MiniPickIconFile') + validate_extmark(ranges_extmarks[2], 1, 'MiniPickMatchRanges') + validate_extmark(ranges_extmarks[3], 1, 'MiniPickMatchRanges') + validate_extmark(ranges_extmarks[4], 1, 'MiniPickMatchRanges') + validate_extmark(ranges_extmarks[5], 2, 'MiniPickIconDirectory') + validate_extmark(ranges_extmarks[6], 2, 'MiniPickMatchRanges') + validate_extmark(ranges_extmarks[7], 2, 'MiniPickMatchRanges') + validate_extmark(ranges_extmarks[8], 2, 'MiniPickMatchRanges') +end + +T['Main view']['works with `content_from_bottom`=true'] = function() + child.set_size(10, 30) + child.lua([[MiniPick.config.options.content_from_bottom = true]]) + local items = { 'a', 'b', 'bb', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7' } + + local validate = function() + child.expect_screenshot() + + type_keys('') + child.expect_screenshot() + + type_keys('b') + child.expect_screenshot() + + type_keys('') + child.expect_screenshot() + + type_keys('') + child.expect_screenshot() + + type_keys('') + end + + -- With `default_show` + start_with_items(items) + validate() + + -- With custom `show` + local lua_cmd = string.format( + [[_G.custom_show = function(buf_id, items, query) + local lines = vim.tbl_map(function(x) return 'Item ' .. x end, items) + -- Lines should still be set as if direction is from top + vim.api.nvim_buf_set_lines(buf_id, 0, -1, false, lines) + end + + MiniPick.start({ source = { items = %s, show = _G.custom_show } })]], + vim.inspect(items) + ) + child.lua_notify(lua_cmd) + validate() +end + +T['Main view']['shows marked items across queries'] = function() + child.set_size(10, 20) + start_with_items({ 'a', 'ab', 'b', 'bb' }) + type_keys('a', 'b', '', '') + child.expect_screenshot() + type_keys('b') + child.expect_screenshot() +end + +T['Main view']['supports vertical scroll'] = function() + child.set_size(10, 15) + + local items = {} + for i = 1, 100 do + items[i] = 'Very big line ' .. i + end + start_with_items(items) + validate_current_ind(1) + + local height = child.api.nvim_win_get_config(get_picker_state().windows.main).height + + -- Vertical scroll should update current item + type_keys('') + validate_current_ind(height + 1) + type_keys('') + validate_current_ind(2 * height + 1) + + type_keys('') + validate_current_ind(height + 1) + type_keys('') + validate_current_ind(1) +end + +T['Main view']['supports horizontal scroll'] = function() + child.set_size(10, 15) + + start_with_items({ 'Short 1', 'Very long item 2', 'Short 3' }) + + -- Horizontal scroll should move window view as if cursor is on current item + type_keys('') + child.expect_screenshot() + type_keys('') + child.expect_screenshot() + -- - Can't move further because cursor is already on the last item column + type_keys('') + child.expect_screenshot() + + -- Moving item at non-trivial right scroll should preserve horizontal + -- view as much as items width allows + type_keys('') + child.expect_screenshot() + + -- Should be able to scroll further horizontally on longer + type_keys('') + child.expect_screenshot() + + -- Should be able to move item from longer to shorter + type_keys('') + child.expect_screenshot() +end + +T['Main view']['properly computes items range to show'] = function() + child.set_size(7, 15) + child.lua_notify([[MiniPick.start({ + source = { items = { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }, + window = { config = { height = 4 } }, + })]]) + + child.expect_screenshot() + for _ = 1, 9 do + type_keys('') + child.expect_screenshot() + end + + for _ = 1, 9 do + type_keys('') + child.expect_screenshot() + end + + for _ = 1, 3 do + type_keys('') + child.expect_screenshot() + end + + for _ = 1, 3 do + type_keys('') + child.expect_screenshot() + end +end + +T['Info view'] = new_set() + +T['Info view']['works'] = function() + child.set_size(40, 60) + child.lua('MiniPick.config.window.config = { height = 40 }') + + start_with_items({ 'a', 'b', 'bb' }, 'My name') + mock_picker_cwd('mock/current-dir') + type_keys('') + child.expect_screenshot() +end + +T['Info view']['respects custom mappings'] = function() + child.set_size(20, 60) + child.lua([[MiniPick.config.mappings.custom_action = { char = '', func = function() print('Hello') end }]]) + child.lua([[MiniPick.config.mappings.another_action = { char = '', func = function() print('World') end }]]) + child.lua([[MiniPick.config.mappings.choose = 'a']]) + child.lua([[MiniPick.config.window.config = { height = 20 }]]) + + start_with_items({ 'a', 'b', 'bb' }, 'My name') + mock_picker_cwd('mock/current-dir') + type_keys('') + child.expect_screenshot() +end + +T['Info view']['uses dedicated highlight groups'] = function() + local validate_extmark = + function(extmark_data, line, hl_group) eq({ extmark_data[2], extmark_data[4].hl_group }, { line - 1, hl_group }) end + + child.lua([[MiniPick.config.mappings.custom_action = { char = '', func = function() print('Hello') end }]]) + start_with_items({ 'a', 'b', 'bb' }, 'My name') + type_keys('') + local buf_id = get_picker_state().buffers.info + + local header_ns_id = child.api.nvim_get_namespaces().MiniPickHeaders + local header_extmarks = child.api.nvim_buf_get_extmarks(buf_id, header_ns_id, 0, -1, { details = true }) + validate_extmark(header_extmarks[1], 1, 'MiniPickHeader') + validate_extmark(header_extmarks[2], 9, 'MiniPickHeader') + validate_extmark(header_extmarks[3], 12, 'MiniPickHeader') +end + +T['Info view']['is updated after moving/marking current item'] = function() + child.set_size(15, 40) + start_with_items({ 'a', 'b', 'bb' }, 'My name') + mock_picker_cwd('mock/current-dir') + type_keys('') + child.expect_screenshot() + + -- Move + type_keys('') + child.expect_screenshot() + + -- Mark + type_keys('') + child.expect_screenshot() + + -- Unmark + type_keys('') + child.expect_screenshot() +end + +T['Info view']['switches to main after query update'] = function() + local validate = function(key) + type_keys('') + validate_picker_view('info') + type_keys(key) + validate_picker_view('main') + end + + start_with_items({ 'a', 'b', 'bb' }, 'My name') + + validate('b') + validate('') + -- Even if query did not change + validate('') +end + +T['Info view']['supports vertical and horizontal scroll'] = function() + start_with_items({ 'a' }) + mock_picker_cwd('mock/current-dir') + type_keys('') + + local validate = function(key) + type_keys(key) + child.expect_screenshot() + end + + validate('') + validate('') + validate('') + validate('') +end + +T['Preview'] = new_set() + +T['Preview']['works'] = function() + start_with_items({ real_file('b.txt') }, 'My name') + type_keys('') + child.expect_screenshot() +end + +T['Preview']['uses dedicated highlight groups'] = function() + local preview_ns_id = child.api.nvim_get_namespaces().MiniPickPreview + local validate_preview_extmark = function(line, pos) + local buf_id = get_picker_state().buffers.preview + local preview_extmarks = child.api.nvim_buf_get_extmarks(buf_id, preview_ns_id, 0, -1, { details = true }) + + eq({ preview_extmarks[1][2], preview_extmarks[1][4].hl_group }, { line - 1, 'MiniPickPreviewLine' }) + if pos ~= nil then + eq({ preview_extmarks[2][2], preview_extmarks[2][4].hl_group }, { pos - 1, 'MiniPickPreviewRegion' }) + end + end + + local path = real_file('b.txt') + local items = { + { text = 'Preview line', path = path, lnum = 3 }, + { text = 'Preview position', path = path, lnum = 4, col = 2 }, + { text = 'Preview region', path = path, lnum = 5, col = 3, end_lnum = 6, end_col = 2 }, + } + start_with_items(items, 'My name') + + type_keys('') + validate_preview_extmark(3, nil, nil) + + type_keys('') + validate_preview_extmark(4, 4) + + type_keys('') + validate_preview_extmark(5, 5) +end + +T['Preview']['is updated after moving current item'] = function() + child.set_size(15, 40) + start_with_items({ 'a', 'b', 'bb' }, 'My name') + type_keys('') + child.expect_screenshot() + + type_keys('') + child.expect_screenshot() +end + +T['Preview']['remains same during (un)marking'] = function() + start_with_items({ 'a', 'b', 'bb' }, 'My name') + type_keys('') + local buf_id = get_picker_state().buffers.preview + eq(child.api.nvim_get_current_buf(), buf_id) + + type_keys('') + eq(child.api.nvim_get_current_buf(), buf_id) + + type_keys('') + eq(child.api.nvim_get_current_buf(), buf_id) +end + +T['Preview']['switches to main after query update'] = function() + local validate = function(key) + type_keys('') + validate_picker_view('preview') + type_keys(key) + validate_picker_view('main') + end + + start_with_items({ 'a', 'b', 'bb' }, 'My name') + + validate('b') + validate('') + -- Even if query did not change + validate('') +end + +T['Preview']['supports vertical and horizontal scroll'] = function() + start_with_items({ real_file('b.txt') }) + type_keys('') + + local validate = function(key) + type_keys(key) + child.expect_screenshot() + end + + validate('') + validate('') + validate('') + validate('') +end + +T['Matching'] = new_set() + +local start_with_items_matchlog = function(items) + child.lua([[ + _G.match_log = {} + _G.match_with_log = function(...) + table.insert(_G.match_log, vim.deepcopy({ ... })) + MiniPick.default_match(...) + end]]) + local lua_cmd = + string.format('MiniPick.start({ source = { items = %s, match = _G.match_with_log } })', vim.inspect(items)) + child.lua_notify(lua_cmd) +end + +local validate_match_log = function(ref) eq(child.lua_get('_G.match_log'), ref) end +local validate_last_match_log = function(ref) eq(child.lua_get('_G.match_log[#_G.match_log]'), ref) end +local clean_match_log = function() child.lua('_G.match_log = {}') end + +T['Matching']['works'] = function() + start_with_items_matchlog({ 'a', 'b', 'bb' }) + -- - `match()` should be called on start for empty query + validate_match_log({ { { 'a', 'b', 'bb' }, { 1, 2, 3 }, {} } }) + clean_match_log() + + -- In regular query increase should use previous match inds (for performance) + type_keys('b') + validate_match_log({ { { 'a', 'b', 'bb' }, { 1, 2, 3 }, { 'b' } } }) + clean_match_log() + + type_keys('b') + validate_match_log({ { { 'a', 'b', 'bb' }, { 2, 3 }, { 'b', 'b' } } }) + clean_match_log() + + type_keys('x') + validate_match_log({ { { 'a', 'b', 'bb' }, { 3 }, { 'b', 'b', 'x' } } }) +end + +T['Matching']['uses stritems'] = function() + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', { text = 'b' }, function() return 'bb' end }, + match = function(...) _G.match_args = { ... }; return { 1 } end, + }})]]) + eq(child.lua_get('_G.match_args'), { { 'a', 'b', 'bb' }, { 1, 2, 3 }, {} }) +end + +T['Matching']['uses cache'] = function() + child.lua('_G.match_n_calls = 0') + local validate_match_calls = function(n_calls_ref, match_inds_ref) + eq(child.lua_get('_G.match_n_calls'), n_calls_ref) + eq(get_picker_matches().all_inds, match_inds_ref) + end + + child.lua_notify([[_G.match_shrink = function(stritems, match_inds, query) + _G.match_n_calls = _G.match_n_calls + 1 + if #query == 0 then return { 1, 2, 3, 4 } end + return vim.list_slice(match_inds, 2, #match_inds) + end]]) + + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'ab', 'b', 'bb' }, match = _G.match_shrink }, + options = { use_cache = true }, + })]]) + + -- As all indexes are matched against empty query when setting them, + -- `match()` should not be called after start + validate_match_calls(0, { 1, 2, 3, 4 }) + + type_keys('b') + validate_match_calls(1, { 2, 3, 4 }) + + type_keys('b') + validate_match_calls(2, { 3, 4 }) + + type_keys('') + validate_match_calls(2, { 2, 3, 4 }) + + type_keys('') + validate_match_calls(2, { 1, 2, 3, 4 }) + + type_keys('b') + validate_match_calls(2, { 2, 3, 4 }) + + type_keys('x') + validate_match_calls(3, { 3, 4 }) + + type_keys('') + validate_match_calls(3, { 1, 2, 3, 4 }) +end + +T['Matching']['resets matched indexes when needed'] = function() + local items = { 'a', 'b', 'bb' } + local validate_all_match_inds = function() validate_last_match_log({ items, { 1, 2, 3 }, get_picker_query() }) end + + start_with_items_matchlog(items) + + -- Any deleting + type_keys('b', 'b') + + type_keys('') + validate_all_match_inds() + + type_keys('') + validate_all_match_inds() + + type_keys('b', 'b', '') + + type_keys('') + validate_all_match_inds() + + type_keys('') + validate_all_match_inds() + + -- Adding character inside query + type_keys('b', '') + type_keys('x') + validate_all_match_inds() + + type_keys('b', 'b', '') + type_keys('x') + validate_all_match_inds() +end + +T['Matching']['allows returning wider than input set of match indexes'] = function() + child.lua_notify([[_G.match_increase = function(stritems, match_inds, query) + if query[#query] == 'x' then return { 1, 2, 3, 4 } end + local prompt_pattern = vim.pesc(table.concat(query)) + return vim.tbl_filter(function(i) return stritems[i]:find(prompt_pattern) ~= nil end, match_inds) + end]]) + + child.lua_notify([[MiniPick.start({ source = { items = { 'a', 'ab', 'b', 'bb' }, match = _G.match_increase } })]]) + type_keys('b', 'b') + eq(get_picker_matches().all_inds, { 4 }) + + type_keys('x') + eq(get_picker_matches().all_inds, { 1, 2, 3, 4 }) +end + +T['Matching']["respects 'ignorecase' and 'smartcase'"] = function() + -- Should precompute and supply lowered versions of stritems and query if + -- case should be ignored. Which to use is computed before every matching. + local items = { 'ab', 'Ab', 'AB' } + local items_lowered = { 'ab', 'ab', 'ab' } + start_with_items_matchlog(items) + + local validate = function(query, ref_state) + set_picker_query(query) + local ref_stritems = ref_state == 'lowered' and items_lowered or items + local ref_query = ref_state == 'lowered' and vim.tbl_map(string.lower, query) or query + validate_last_match_log({ ref_stritems, { 1, 2, 3 }, ref_query }) + clean_match_log() + type_keys('') + end + + child.o.ignorecase, child.o.smartcase = false, false + validate({ 'ab' }, 'non-lowered') + validate({ 'Ab' }, 'non-lowered') + validate({ 'AB' }, 'non-lowered') + + child.o.ignorecase, child.o.smartcase = true, false + validate({ 'ab' }, 'lowered') + validate({ 'Ab' }, 'lowered') + validate({ 'AB' }, 'lowered') + + child.o.ignorecase, child.o.smartcase = false, true + validate({ 'ab' }, 'non-lowered') + validate({ 'Ab' }, 'non-lowered') + validate({ 'AB' }, 'non-lowered') + + child.o.ignorecase, child.o.smartcase = true, true + validate({ 'ab' }, 'lowered') + validate({ 'Ab' }, 'non-lowered') + validate({ 'AB' }, 'non-lowered') +end + +T['Matching']['uses proper `tolower` for ignoring case'] = function() + local items, items_lowered = { 'ыф', 'Ыф', 'ЫФ' }, { 'ыф', 'ыф', 'ыф' } + start_with_items_matchlog(items) + + child.o.ignorecase, child.o.smartcase = true, false + type_keys('ы') + validate_last_match_log({ items_lowered, { 1, 2, 3 }, { 'ы' } }) + type_keys('Ф') + validate_last_match_log({ items_lowered, { 1, 2, 3 }, { 'ы', 'ф' } }) + type_keys('') + + child.o.ignorecase, child.o.smartcase = true, true + type_keys('ы') + validate_last_match_log({ items_lowered, { 1, 2, 3 }, { 'ы' } }) + type_keys('Ф') + validate_last_match_log({ items, { 1, 2, 3 }, { 'ы', 'Ф' } }) +end + +T['Key query process'] = new_set() + +T['Key query process']['respects mouse click'] = function() + helpers.skip_in_ci('Can not make this work consistently in CI.') + + child.set_size(10, 15) + + -- Should ignore if inside main window + local validate_press_inside = function(button, row, col) + child.api.nvim_input_mouse(button, 'press', '', 0, row, col) + eq(is_picker_active(), true) + end + + start_with_items({ 'a' }) + + -- - Press on all four courners + validate_press_inside('left', 2, 0) + validate_press_inside('left', 8, 0) + validate_press_inside('left', 8, 10) + validate_press_inside('left', 2, 10) + + -- - Actual button should not matter + validate_press_inside('right', 2, 0) + validate_press_inside('middle', 2, 0) + + type_keys('') + + -- Should stop picker if outside of main window + local validate_press_outside = function(button, row, col) + start_with_items({ 'a' }) + child.api.nvim_input_mouse(button, 'press', '', 0, row, col) + sleep(10) + eq(is_picker_active(), false) + end + + validate_press_outside('left', 1, 0) + validate_press_outside('left', 9, 0) + validate_press_outside('left', 9, 10) + validate_press_outside('left', 8, 11) + validate_press_outside('left', 1, 10) + validate_press_outside('left', 2, 11) + + validate_press_outside('right', 1, 0) + validate_press_outside('middle', 1, 0) +end + +T['Key query process']['handles not configured key presses'] = function() + start_with_items({ 'a' }) + + -- Should not add them to query + local validate = function(key) + type_keys(key) + eq(get_picker_query(), {}) + end + + validate('') + validate('') + validate('') + validate('\1') + validate('\31') +end + +T['Key query process']['always stops on ``'] = function() + child.api.nvim_set_keymap('n', '', 'echo 1', {}) + start_with_items({ 'a' }) + type_keys('') + eq(is_picker_active(), false) +end + +T['Caret'] = new_set({ hooks = { pre_case = function() child.set_size(10, 15) end } }) + +local validate_caret = function(n) eq(get_picker_state().caret, n) end + +T['Caret']['works'] = function() + start_with_items({ 'a' }) + validate_caret(1) + + -- Should move along right edge + type_keys('a') + validate_caret(2) + + type_keys('b') + validate_caret(3) + + -- Should insert character at its place + type_keys('', 'c') + validate_caret(3) + child.expect_screenshot() + + -- Should delete character at its place + type_keys('') + validate_caret(2) + child.expect_screenshot() + + type_keys('') + validate_caret(2) + child.expect_screenshot() +end + +T['Caret']['moves by query parts'] = function() + start_with_items({ 'a' }) + set_picker_query({ 'ab', 'cd' }) + validate_caret(3) + child.expect_screenshot() + + type_keys('') + validate_caret(2) + child.expect_screenshot() + + type_keys('') + validate_caret(1) + child.expect_screenshot() +end + +T['Caret']['can not go past query boundaries'] = function() + start_with_items({ 'a' }) + type_keys('') + validate_caret(1) + type_keys('') + validate_caret(1) + + type_keys('a', 'b', '') + validate_caret(3) + type_keys('', '', '') + validate_caret(1) +end + +T['Caret']['works without items'] = function() + start_with_items() + type_keys('') + validate_caret(1) + type_keys('') + validate_caret(1) +end + +T['Choose'] = new_set() + +T['Choose']['works for split/tab variations'] = function() + local validate = function(key) + local win_id_init = child.api.nvim_get_current_win() + child.lua_notify([[MiniPick.start({ + source = { + items = { 'a' }, + choose = function() _G.target_window = MiniPick.get_picker_state().windows.target end, + }, + })]]) + + type_keys(key) + -- Should create split/tab + child.expect_screenshot() + -- Should modify target window + eq(child.lua_get('_G.target_window') ~= win_id_init, true) + + -- Cleanup + child.lua('_G.target_window = nil') + end + + validate('') + validate('') + validate('') +end + +T['Choose']['works without items'] = function() + local validate = function(key) + child.lua_notify('MiniPick.start({ source = { choose = function(...) _G.been_here = true end } })') + type_keys(key) + -- Should not do any split/tab + eq(#child.api.nvim_list_wins(), 1) + -- Should not call `source.choose()` function + eq(child.lua_get('_G.been_here'), vim.NIL) + end + + validate('') + validate('') + validate('') + validate('') +end + +T['Choose']['works with no matching items'] = function() + local validate = function(key) + child.lua_notify([[MiniPick.start({ + source = { items = { 'a' }, choose = function(...) _G.been_here = true end }, + })]]) + type_keys('b', key) + -- Should not do any split/tab + eq(#child.api.nvim_list_wins(), 1) + -- Should not call `source.choose()` function + eq(child.lua_get('_G.been_here'), vim.NIL) + end + + validate('') + validate('') + validate('') + validate('') +end + +T['Choose']['uses output as "should continue"'] = function() + local validate = function(key) + child.lua_notify([[MiniPick.start({ + source = { + items = { 'a', 'b' }, + choose = function(item) _G.latest_item = item; return item == 'a' end, + choose_marked = function(items) _G.latest_item = items[#items]; return #items == 1 end, + }, + })]]) + + type_keys(key) + eq(child.lua_get('_G.latest_item'), 'a') + eq(is_picker_active(), true) + + type_keys('', key) + eq(child.lua_get('_G.latest_item'), 'b') + eq(is_picker_active(), false) + end + + validate('') + validate('') + validate('') + validate('') + + validate({ '', '' }) +end + +T['Mark'] = new_set() + +T['Mark']['works'] = function() + local validate = function(keys, marked_items) + child.lua_notify([[MiniPick.start({ source = { + items = { 'a', 'b', 'bb' }, + choose_marked = function(items) _G.choose_marked_items = items end, + } })]]) + type_keys(keys) + type_keys('') + eq(child.lua_get('_G.choose_marked_items'), marked_items) + eq(is_picker_active(), false) + end + + validate({ '' }, { 'a' }) + validate({ '', '', '' }, { 'a', 'b' }) + + -- Should be returned in the original order, not how they were marked + validate({ '', '', '', '' }, { 'a', 'b' }) + + -- Should not return unmarked item + validate({ '', '' }, {}) + + -- Marked items should be preserved across queries + validate({ 'b', '', '', '', 'a', '' }, { 'a', 'bb' }) + + -- Works with 'mark_all': mark all if not all marked, unmark otherwise + validate({ '' }, { 'a', 'b', 'bb' }) + validate({ '', '' }, { 'a', 'b', 'bb' }) + validate({ '', '' }, {}) +end + +T['Mark']['works without items set'] = function() + child.set_size(5, 15) + start_with_items() + type_keys('') + type_keys('') + child.expect_screenshot() +end + +T['Move'] = new_set() + +T['Move']['works'] = function() + start_with_items({ 'a', 'b', 'bb', 'bbb' }) + + -- Next/prev + type_keys('') + validate_current_ind(2) + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(2) + + -- First + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(1) +end + +T['Move']['works with non-overridable keys'] = function() + start_with_items({ 'a', 'b', 'bb', 'bbb' }) + + type_keys('') + validate_current_ind(2) + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(2) + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(1) +end + +T['Move']['next/prev wraps around edges'] = function() + start_with_items({ 'a', 'b' }) + + type_keys('') + validate_current_ind(2) + type_keys('') + validate_current_ind(1) + + type_keys('') + validate_current_ind(2) + type_keys('') + validate_current_ind(1) +end + +T['Move']['scrolls to edge without wrap and then wraps'] = function() + start_with_items({ 'a', 'b', 'bb' }) + + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(1) + + type_keys('') + validate_current_ind(3) + type_keys('') + validate_current_ind(1) +end + +T['Move']['works when no items are set'] = function() + child.set_size(5, 15) + start_with_items() + type_keys('') + type_keys('') + type_keys('') + child.expect_screenshot() +end + +T['Paste'] = new_set() + +T['Paste']['works'] = function() + child.set_size(5, 15) + local validate = function(regcontents, ref_query) + child.fn.setreg('a', regcontents) + start_with_items({ 'a' }) + type_keys('', 'a') + eq(get_picker_query(), ref_query) + child.expect_screenshot() + type_keys('') + end + + validate('hello', { 'h', 'e', 'l', 'l', 'o' }) + validate('ыфя', { 'ы', 'ф', 'я' }) + + -- Should sanitize register content + validate('a\nb\tc', { 'a', ' ', 'b', ' ', 'c' }) +end + +T['Paste']['pastes at caret'] = function() + child.fn.setreg('a', 'hello ') + start_with_items({ 'a' }) + type_keys('w', 'o', 'r', 'l', 'd') + type_keys('', '', '', '', '') + type_keys('', 'a') + eq(get_picker_query(), { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }) +end + +T['Paste']['does not error on non-existing register label'] = function() + start_with_items({ 'a' }) + type_keys('', '') + eq(get_picker_query(), {}) + type_keys('a') + eq(get_picker_query(), { 'a' }) +end + +T['Paste']['respects `delay.async` when waiting for register label'] = function() + child.set_size(15, 15) + child.lua_notify([[ + _G.buf_id, _G.n = vim.api.nvim_get_current_buf(), 0 + local timer = vim.loop.new_timer() + local f = vim.schedule_wrap(function() + _G.n = _G.n + 1 + vim.fn.appendbufline(_G.buf_id, '$', { 'Line ' .. _G.n }) + end) + timer:start(50, 50, f) + ]]) + local validate = function(n, lines) + eq(child.lua_get('_G.n'), n) + eq(child.lua_get('vim.api.nvim_buf_get_lines(_G.buf_id, 0, -1, false)'), lines) + child.expect_screenshot() + end + + child.lua_notify([[MiniPick.start({ source = { items = { 'a' } }, delay = { async = 80 } })]]) + validate(0, { '' }) + type_keys('') + + -- Callback should have already been executed, but not redraw + sleep(50 + 5) + validate(1, { '', 'Line 1' }) + + -- No new callback should have been executed, but redraw should + sleep(30) + validate(1, { '', 'Line 1' }) + + -- Test that redraw is done repeatedly + sleep(80) + validate(3, { '', 'Line 1', 'Line 2', 'Line 3' }) +end + +T['Refine'] = new_set() + +T['Refine']['works'] = function() + child.set_size(10, 15) + start_with_items({ 'a', 'ab', 'b', 'ba', 'bb' }, 'My name') + + type_keys('b') + child.expect_screenshot() + + type_keys('') + -- - Should use matches in the sorted order, not their original one. + -- - Also should remove matched ranges highlight. + child.expect_screenshot() + -- - Should reset data and update name + validate_picker_option('source.name', 'My name (Refine)') + + -- Can be used several times + type_keys('a') + type_keys('') + child.expect_screenshot() + validate_picker_option('source.name', 'My name (Refine 2)') +end + +T['Refine']['works with marked'] = function() + child.set_size(10, 15) + start_with_items({ 'a', 'b', 'c' }, 'My name') + + type_keys('', '', '', '') + type_keys('') + eq(get_picker_items(), { 'b', 'c' }) + validate_picker_option('source.name', 'My name (Refine)') + + -- Can be used several times + type_keys('') + type_keys('') + eq(get_picker_items(), { 'b', 'c' }) + validate_picker_option('source.name', 'My name (Refine 2)') +end + +T['Refine']['uses config match'] = function() + child.lua_notify([[MiniPick.start({ + source = { items = { 'a', 'b', 'bb' }, name = 'My name', match = function() return { 1, 2, 3 } end }, + })]]) + + type_keys('b') + eq(get_picker_matches().all_inds, { 1, 2, 3 }) + type_keys('') + type_keys('b') + eq(get_picker_matches().all_inds, { 2, 3 }) +end + +T['Refine']['works when no items are set'] = function() + child.set_size(5, 15) + start_with_items() + type_keys('') + type_keys('') + child.expect_screenshot() +end + +T['Stop'] = new_set() + +T['Stop']['triggers User event'] = function() + child.cmd('au User MiniPickStop lua _G.track_event()') + local validate = function(key) + make_event_log() + start_with_items({ 'a', 'b', 'bb' }) + type_keys('b', key) + eq(child.lua_get('_G.event_log'), { 2 }) + end + + validate('') + validate('') +end + +return T