-
Notifications
You must be signed in to change notification settings - Fork 195
feat: add auto_complete_menu option for IDE-style completions #993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Adds a new `with_auto_complete_menu(enable: bool)` builder method that enables automatic completion menu display as you type, similar to fish shell and modern IDEs. When enabled: - Completion menu appears after typing 1+ character for any argument - Menu deactivates when typing just a space (waiting for next word) - First word (commands) never auto-completes - Prevents scroll jank by only activating menu once Also adds CompletionHinter for inline gray-text suggestions from the completer (fish-style), though this is separate from the menu feature.
Adds `$env.config.completions.auto_menu` option (default: false) that enables automatic completion menu display as you type. When enabled: - Completion menu appears after typing 1+ character for any argument - Menu deactivates when typing just a space (waiting for next word) - First word (commands) never auto-completes Also switches hint provider from CwdAwareHinter to CompletionHinter for fish-style inline suggestions based on completions rather than history. Requires: nushell/reedline#993
|
A potentially stupid question: I don't see any Or, by |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this!
I like the idea of a CompletionHinter, but it seems unrelated to the auto_complete_menu change and should be split into a separate PR
| false | ||
| }; | ||
|
|
||
| if let Some(menu) = self.menus.iter_mut().find(|m| m.name() == "completion_menu") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of the menu name being hardcoded here. I'd rather auto_complete_menu be an Option<String> holding the name of the menu to activate automatically. That way, users can choose which menu they want to always be active.
| hide_hints: bool, | ||
|
|
||
| // Auto-show completion menu as you type (IDE/fish style) | ||
| auto_complete_menu: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this name can confuse people. auto_complete_menu sounds like it's a menu for autocompletion, which all the menus are for. I'd prefer always_on_menu or something like that
| hinter: Option<Box<dyn Hinter>>, | ||
| hide_hints: bool, | ||
|
|
||
| // Auto-show completion menu as you type (IDE/fish style) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You say "IDE" here, but looking at your code, it won't necessarily pick the IdeMenu, it'll pick whichever menu is named completion_menu. I think you just happened to see the IDE menu because that's what you have set in your Nushell config.
But also, let's not restrict this feature to the IDE menu. I prefer the columnar menu myself and would like to use that. So you can just remove the "(IDE/fish style)" bit from this comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment just explain what the author means by "as you type", since in IDE like vscode completion is shown as you type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment just explain what the author means by "as you type", since in IDE like vscode completion is shown as you type.
The thing is that "IDE" in reedline context has sort of special meaning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely, but given that it appears next to fish I don't think it relates to this internal meaning. Nevermind it's just a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely, but given that it appears next to
fishI don't think it relates to this internal meaning. Nevermind it's just a comment.
I'd prefer precise comments.
| // - Files/args: show after 1+ chars typed (not just space) | ||
| // - Commands (first word): don't auto-complete | ||
| let buffer = self.editor.line_buffer().get_buffer(); | ||
| let should_show = if let Some(last_word_start) = buffer.rfind(' ') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to make it so that the menu is always active, even if it's after a space. Let's leave it up to the menu and completer to decide whether to show anything.
I know this means users will see "NO RECORDS" all the time, but I'm sure we can work around that (or just let it be).
@blindFS thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit tricky.
On one side, there should be a configurable min-triggering-characters to lower the frequency.
However spaces are sometimes meaningful characters for fuzzy/substring matcher.
Seems to me a pure reedline solution won't be "smart" enough in that sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just for the fuzzy/substring matchers, I'm thinking about a scenario where someone has a command foo that can only take one fruit as an argument: apple or banana. So if I type foo <TAB>, I want to see the options apple and banana, even if I haven't typed anything yet
And yeah, it's out of scope for Reedline to guess how a completer works. The only time that disabling the menu is probably safe is when the user hasn't typed anything at all yet (empty buffer)
| if !menu.is_active() { | ||
| // Only activate if not already active | ||
| menu.menu_event(MenuEvent::Activate(self.quick_completions)); | ||
| menu.update_values( | ||
| &mut self.editor, | ||
| self.completer.as_mut(), | ||
| self.history.as_ref(), | ||
| ); | ||
| } else { | ||
| // Menu already active, just send edit event to update | ||
| menu.menu_event(MenuEvent::Edit(self.quick_completions)); | ||
| menu.update_values( | ||
| &mut self.editor, | ||
| self.completer.as_mut(), | ||
| self.history.as_ref(), | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick (pardon the indentation)
| if !menu.is_active() { | |
| // Only activate if not already active | |
| menu.menu_event(MenuEvent::Activate(self.quick_completions)); | |
| menu.update_values( | |
| &mut self.editor, | |
| self.completer.as_mut(), | |
| self.history.as_ref(), | |
| ); | |
| } else { | |
| // Menu already active, just send edit event to update | |
| menu.menu_event(MenuEvent::Edit(self.quick_completions)); | |
| menu.update_values( | |
| &mut self.editor, | |
| self.completer.as_mut(), | |
| self.history.as_ref(), | |
| ); | |
| } | |
| if !menu.is_active() { | |
| // Only activate if not already active | |
| menu.menu_event(MenuEvent::Activate(self.quick_completions)); | |
| } else { | |
| menu.menu_event(MenuEvent::Edit(self.quick_completions)); | |
| } | |
| menu.update_values( | |
| &mut self.editor, | |
| self.completer.as_mut(), | |
| self.history.as_ref(), | |
| ); |
|
Thanks a lot for this feature that I've been waiting for to start adopting nushell given how much I like zfs_autocomplete in powerlevel10k. That being said, I'm a bit worried by this:
since I often really like seeing in zfs suggestions right after typing space. For instance just typing Similarly for
In zfs it also proposes autocompletion of the command as I type and it is really practical. Would you consider putting these behind options to allow people like me to enable these options? |
Summary
with_auto_complete_menu(enable: bool)builder method to ReedlineCompletionHinterfor inline gray-text suggestionsMotivation
Many users coming from fish shell expect completions to appear automatically without pressing Tab. This provides an opt-in way to enable that behavior.
Test plan
cargo build$env.config.completions.auto_menu = truels -) and files (ls d)ls --all)