Open HKalbasi opened 3 months ago
Would be nice to see a gif/video of what this looks like and a better description so that reviewers don't have to jump around figuring out what this PR is supposed to do.
Sure! This PR adds some configs to menus:
activate_on_start
: if true, menu will be activated at the start of every prompt, when the editor is empty.keep_active_after_accept
: Keeps the menu enabled even when it's suggestion is accepted.By enabling these configs, menu will be open on start and remain open unless user manually close it with ESC
or something similar. The problem is that now it is impossible to actually submit the prompt without manually closing the menu since the menu always capture the Enter
event. So I added two other things:
ReedlineEvent::MenuAccept
: a Submit
like event specific to menus, which keys like Tab
can bound it.treat_submit_as_accept
menu config: if true (which is the default), Submit
and Enter
events accept the menu suggestion.All together, we can keep completion menu always open while accepting prompts at the same time with Enter
:
It is not very clear in the video, but I don't press any key for activating the menu and it is always enabled. I use completion with Tab
and submit prompts with Enter
. I added the change into the example ide_completions
so you can execute it yourself if the video is not clear enough. Also I can create another example if you want to keep that example unchanged or remove it if it is not desired.
This is an interesting feature and a good start but I'm getting a panic somewhere when accepting an entry.
It's also weird that I can't use Enter to accept an item in the list. I'm not sure Tab will be a good "accept" since it's used to complete things.
All very interesting and it reminds me of pwsh's menu, which I just love.
I'm getting a panic somewhere when accepting an entry.
I'm not able to reproduce the panic. Can you give me the stack trace of it or some way to reproduce it? Does it happen when you do some specific thing?
It's also weird that I can't use Enter to accept an item in the list. I'm not sure Tab will be a good "accept" since it's used to complete things.
It is configurable and can be disabled, but without it, user needs to manually close the menu with ESC before submitting the prompt.
Another way to address this problem is how prompt_toolkit
python library does: in prompt toolkit, the completion menu is always open, but it doesn't select any item, and when an item is selected, it is implicitly accepted and user don't need to press anything to accept the suggestion and can just continue the typing:
In this way, the Enter key is free for submitting the prompt, and Tab is used for switching between the menu items. I can add configuration for this as well if desired.
I'm not able to reproduce the panic. Can you give me the stack trace of it or some way to reproduce it? Does it happen when you do some specific thing?
It's some combination of hitting tab, backspace or tab, enter, backspace.
❯ cargo r --example ide_completions 10:27:34 AM
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.19s
Running `target\debug\examples\ide_completions.exe`
~\source\repos\reedline| hello another very large option for hello word that will force one column08/30/2024 10:28:01 AM
We processed: hello another very large option for hello word that will force one column
~\source\repos\reedline| hello another very large option for hello word that will force one columnthread 'main' panicked at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\str\mod.rs:659:21:
byte index 72 is out of bounds of `hello another very large option for hello word ...`
stack backtrace:
0: 0x7ff76579ecad - std::backtrace_rs::backtrace::dbghelp64::trace
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:91
1: 0x7ff76579ecad - std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
2: 0x7ff76579ecad - std::sys_common::backtrace::_print_fmt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\sys_common\backtrace.rs:68
3: 0x7ff76579ecad - std::sys_common::backtrace::_print::impl$0::fmt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\sys_common\backtrace.rs:44
4: 0x7ff7657b8099 - core::fmt::rt::Argument::fmt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\fmt\rt.rs:165
5: 0x7ff7657b8099 - core::fmt::write
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\fmt\mod.rs:1168
6: 0x7ff76579b341 - std::io::Write::write_fmt<std::sys::pal::windows::stdio::Stderr>
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\io\mod.rs:1835
7: 0x7ff76579ea86 - std::sys_common::backtrace::print
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\sys_common\backtrace.rs:34
8: 0x7ff7657a0bf8 - std::panicking::default_hook::closure$1
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:271
9: 0x7ff7657a08a6 - std::panicking::default_hook
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:298
10: 0x7ff7657a1128 - std::panicking::rust_panic_with_hook
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:795
11: 0x7ff7657a0fe7 - std::panicking::begin_panic_handler::closure$0
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:664
12: 0x7ff76579f61f - std::sys_common::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\sys_common\backtrace.rs:171
13: 0x7ff7657a0c98 - std::panicking::begin_panic_handler
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652
14: 0x7ff7657beed4 - core::panicking::panic_fmt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72
15: 0x7ff7657ba1c4 - core::str::slice_error_fail_rt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\str\mod.rs:112
16: 0x7ff7657bf5f8 - core::str::slice_error_fail
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\str\mod.rs:89
17: 0x7ff7656fd43d - core::str::impl$0::split_at
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\str\mod.rs:659
18: 0x7ff7656b366a - reedline::menu::ide_menu::IdeMenu::create_value_string
at C:\Users\fdncred\source\repos\reedline\src\menu\ide_menu.rs:518
19: 0x7ff765721838 - reedline::menu::ide_menu::impl$6::menu_string::closure$0
at C:\Users\fdncred\source\repos\reedline\src\menu\ide_menu.rs:865
20: 0x7ff7656fe93e - core::iter::adapters::map::map_fold::closure$0<tuple$<usize,ref$<reedline::completion::base::Suggestion> >,alloc::string::String,tuple$<>,reedline::menu::ide_menu::impl$6::menu_string::closure_env$0,core::iter::traits::iterator::Iterator::for_each::call::c
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\map.rs:89
21: 0x7ff7656f89b6 - core::iter::adapters::enumerate::impl$1::fold::enumerate::closure$0<ref$<reedline::completion::base::Suggestion>,tuple$<>,core::iter::adapters::map::map_fold::closure_env$0<tuple$<usize,ref$<reedline::completion::base::Suggestion> >,alloc::string::String,t
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\enumerate.rs:108
22: 0x7ff76570543c - core::iter::adapters::take::impl$10::spec_fold<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> >,tuple$<>,core::iter::adapters::enumerate::impl$1::fold::enumerate::closure_env$0<ref$<reedline::completion::ba
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\take.rs:307
23: 0x7ff765703ba9 - core::iter::adapters::take::impl$1::fold<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> >,tuple$<>,core::iter::adapters::enumerate::impl$1::fold::enumerate::closure_env$0<ref$<reedline::completion::base::Su
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\take.rs:110
24: 0x7ff7656f8817 - core::iter::adapters::enumerate::impl$1::fold<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> > >,tuple$<>,core::iter::adapters::map::map_fold::closure_env$0<tuple$<usize,ref
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\enumerate.rs:114
25: 0x7ff7656fd681 - core::iter::adapters::map::impl$2::fold<alloc::string::String,core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> > > >,reedline::menu:
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\adapters\map.rs:129
26: 0x7ff7656fe4b8 - core::iter::traits::iterator::Iterator::for_each<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> > >
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\traits\iterator.rs:818
27: 0x7ff7656ec30a - alloc::vec::Vec<alloc::string::String,alloc::alloc::Global>::extend_trusted<alloc::string::String,alloc::alloc::Global,core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Sk
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\alloc\src\vec\mod.rs:3096
28: 0x7ff7656f137e - alloc::vec::spec_extend::impl$1::spec_extend<alloc::string::String,core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::bas
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\alloc\src\vec\spec_extend.rs:26
29: 0x7ff7656ea0e2 - alloc::vec::spec_from_iter_nested::impl$1::from_iter<alloc::string::String,core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::complet
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\alloc\src\vec\spec_from_iter_nested.rs:62
30: 0x7ff7656f1551 - alloc::vec::spec_from_iter::impl$0::from_iter<alloc::string::String,core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::ba
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\alloc\src\vec\spec_from_iter.rs:33
31: 0x7ff7656f10b7 - alloc::vec::impl$15::from_iter<alloc::string::String,core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion>
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\alloc\src\vec\mod.rs:2970
32: 0x7ff7656fe441 - core::iter::traits::iterator::Iterator::collect<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::take::Take<core::iter::adapters::skip::Skip<core::slice::iter::Iter<reedline::completion::base::Suggestion> > >
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\iter\traits\iterator.rs:2005
33: 0x7ff7656b576a - reedline::menu::ide_menu::impl$6::menu_string
at C:\Users\fdncred\source\repos\reedline\src\menu\ide_menu.rs:855
34: 0x7ff765707bf6 - reedline::menu::impl$4::menu_string
at C:\Users\fdncred\source\repos\reedline\src\menu\mod.rs:484
35: 0x7ff76570df4c - reedline::painting::painter::Painter::print_menu
at C:\Users\fdncred\source\repos\reedline\src\painting\painter.rs:307
36: 0x7ff76570e7b4 - reedline::painting::painter::Painter::print_small_buffer
at C:\Users\fdncred\source\repos\reedline\src\painting\painter.rs:359
37: 0x7ff76570d4ea - reedline::painting::painter::Painter::repaint_buffer
at C:\Users\fdncred\source\repos\reedline\src\painting\painter.rs:234
38: 0x7ff7656c15aa - reedline::engine::Reedline::buffer_paint
at C:\Users\fdncred\source\repos\reedline\src\engine.rs:1842
39: 0x7ff7656c02ed - reedline::engine::Reedline::repaint
at C:\Users\fdncred\source\repos\reedline\src\engine.rs:1544
40: 0x7ff7656ba63a - reedline::engine::Reedline::read_line_helper
at C:\Users\fdncred\source\repos\reedline\src\engine.rs:805
41: 0x7ff7656b9c73 - reedline::engine::Reedline::read_line
at C:\Users\fdncred\source\repos\reedline\src\engine.rs:649
42: 0x7ff7656a1f02 - ide_completions::main
at C:\Users\fdncred\source\repos\reedline\examples\ide_completions.rs:123
43: 0x7ff7656a10ab - core::ops::function::FnOnce::call_once<enum2$<core::result::Result<tuple$<>,std::io::error::E~\source\repos\reedline| hello another very large option for hello word that will force one columerror: process didn't exit successfully: `target\debug\examples\ide_completions.exe` (exit code: 101)
~\source\repos\reedline> [keep-menu-always-open]
The panic also happens in the main branch. I will fix it in a separate PR.
now that the bug is out of the way, i'm thinking about this "implicit acceptance" you demonstrated above. i'm wondering what the most ergonomic way is to interact with a menu that is open all the time.
Very appealing feature! Is it still working in process? I can help if any.
The problem here is to find the best ergonomic way for accepting when the menu is still open. I'm open to implement the prompt toolkit way if desired, and I think since this feature is opt-in we can merge this PR for now and wait for people to use the feature and come with more ideas.
FYI: my use case is to pop up the menu when a key is pressed. Maybe we can provide a custom event hook which can rewrite to edit action or discard an input event.
Can you check if this PR as its current state satisfy your needs?
I'd like to close the menu when the cursor is right after a whitespace. Can this PR achieve that?
I think you can set an event for the space key to do that, but I'm not sure.
fix #820