Skip to content
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

Automatically register and improve CLI completions for the dotnet CLI #42397

Open
baronfel opened this issue Jul 26, 2024 · 2 comments
Open

Automatically register and improve CLI completions for the dotnet CLI #42397

baronfel opened this issue Jul 26, 2024 · 2 comments
Labels
Area-CLI cli-ux Issues and PRs that deal with the UX of the CLI (exit codes, log output, verbs/options, and so on) Epic Groups multiple user stories. Can be grouped under a theme. untriaged Request triage from a team member

Comments

@baronfel
Copy link
Member

baronfel commented Jul 26, 2024

Is your feature request related to a problem? Please describe.

The dotnet CLI today has pervasive completion support for commands, options, and arguments. However, our telemetry data suggests that very few users do the configuration required to enable completion support in their shells. In the recent CLI usability study, the top-requested item across all users regardless of experience levels, IDE, or OS was automatic registration of CLI completions and more pervasive and informative completions across the CLI commands (and commands that feel like they are part of the dotnet CLI).

Describe the solution you'd like

The dotnet CLI should

  • reduce the work required to register tab completions for shells,
  • invest in statically-generated completion scripts, and
  • expand the information provided from completions to include help descriptions and other reference information

This will bring the CLI in-line with patterns used by other widely-used CLI tools, vastly improve the user experience of the CLI, and improve the performance of completions all-up.

Reduce the work required to register tab completions for shells

Today, users configure completion for their shells by manually inserting shell-specific completion scripts into their shell-specific profile scripts - scripts that shells either explicitly or implicitly by convention load when starting or requesting completions for a command. These scripts are 'frozen' in time and users have to remember to update them if CLI capabilities change.

Instead, we should provide a two new commands to make this process easier:

  • dotnet completions script [<SHELL>]
    • emits the completions script for a particular SHELL to stdout, with no other output allowed from the CLI
    • if no SHELL is specified, infers the shell from the users $SHELL environment variable
  • dotnet completions register [<SHELL>]
    • inserts a shell-specific call to dotnet completions script <SHELL> into a shell-specific completions script location
    • if no SHELL is specified, infers the shell from the users $SHELL environment variable
    • There's a lot of prior art for installation/uninstallation in the golang complete package (MIT licensed).

We should also extend the first-run experience to prompt the user for permission to perform the register command on first-run, but only if the current shell is interactive (meaning a user is at the keyboard). There is an existing go/bash convention for this: COMP_INSTALL=1 and COMP_UNINSTALL=1 environment variables signal willingness to automatically configure and remove completions for programs.

Invest in statically-generated completion scripts

With the previous step done, we now have a way to solve the 'out of date completions script' problem. User shells will automatically generate and load completions scripts on each load, so the dotnet CLI can begin investments in generating better scripts.

The first iteration of the dotnet completions script [<SHELL>] command would only emit the 'dynamic' completion script that we ask users to set up today. However, subsequent iterations should generate scripts that are more static - meaning they generation completions without having to call dotnet complete, instead relying on the features of the different shell completion systems to prevent the need to spawn dotnet processes (with all the overhead that entails) and enable better shell-completion-system integration and performance overall.

This can be done opportunistically and at different levels for different shells, because many shells have varying degrees of sophistication here.

Expand the information provided from completions

Today, all completions for the dotnet CLI provide only the completion value. The underlying System.CommandLine completions subsystem allows for providing more details, like descriptions or extended help for a given completion item. The completions systems for different shells are often capable of rendering this information inline when completions are requested, but it has been hard to provide that information in a way that didn't invalidate the existing shell script shims that users have added to their profiles.

With dotnet completions register [<$SHELL>] all of these blockers are removed and we can create new completion commands to provide whatever level of context is required. At minimum we should provide descriptions and integrate them into the statically-generated completions from the previous section.

@baronfel baronfel added Epic Groups multiple user stories. Can be grouped under a theme. cli-ux Issues and PRs that deal with the UX of the CLI (exit codes, log output, verbs/options, and so on) labels Jul 26, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-CLI untriaged Request triage from a team member labels Jul 26, 2024
@KalleOlaviNiemitalo
Copy link
Contributor

How would statically-generated completion scripts work with global.json files in different directories specifying different versions of .NET SDK; would you make the shell parse JSON and choose the appropriate completion script?

@baronfel
Copy link
Member Author

That's a potential problem, but per telemetry the vast majority of .NET projects do not use global.json at all so it's not a scenario I'm incredibly worried about. In many ways the source (dotnet completions generate bash) pattern in your $PROFILE actually helps in multi-version scenarios - if you have one shell per project then the dotnet selected by the global.json at shell creation would generate the completions, so you get a greater likelihood of alignment there.

For more complex scenarios than that I don't think we'd spend much time trying to handle that - the CLI itself has a pretty high compat bar for commands/flags/etc so completions from older versions should still be correct/relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CLI cli-ux Issues and PRs that deal with the UX of the CLI (exit codes, log output, verbs/options, and so on) Epic Groups multiple user stories. Can be grouped under a theme. untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests

2 participants