dotnet / command-line-api

Command line parsing, invocation, and rendering of terminal output.
https://github.com/dotnet/command-line-api/wiki
MIT License
3.4k stars 381 forks source link

ICompletionSource for file paths? #1697

Open AArnott opened 2 years ago

AArnott commented 2 years ago

A tool that accepts directory or file paths as arguments gets unhelpful completions suggested, as the user only gets other options -- never files. Is there a file path implementation of ICompletionSource anywhere?

jonsequitur commented 2 years ago

There isn't one currently because typically the shell will fall back to file completion if the shim doesn't receive any completions from the .NET tool.

There's been some discussion of providing specialized file completions, e.g. suggesting files that match a specific file extension, possibly recursively.

AArnott commented 2 years ago

The trouble I'm having is the shell (powershell) doesn't fill in file paths at all at the expected times. Given what you say, maybe that means that dotnet-suggest offers completions where perhaps it shouldn't. Check out how in the animated gif below, the usage doc describes paths coming before options. Yet when I press tab, only options are listed. Even if I start to type a path and press tab, it'll be replaced by an option with a similar prefix instead of the file path I was typing. This happens a lot and seriously undermines the value of dotnet-suggest (which is a great idea). Can we perhaps only have it offer option completions when file paths are not expected, or perhaps when the user has already typed a hyphen?

95318b2f-474c-425b-9068-c31ee65e58be

jonsequitur commented 2 years ago

I think I see what's happening. At the position where you're asking for completions, the option tokens are valid, so dotnet-suggest returning any results at all prevents the shell from falling through to the file system completions the way I described earlier. A potential solution here is to deliberately provide file system completions so that the parser will understand that they're equally valid at that position. I suspect we'll want to provide this somewhat independently of the Argument<T> / Option<T> ValueType, although we can be smart about Argument<FileInfo> versus Argument<DirectoryInfo>. (Now I'm going to go be vaguely uneasy about glob expansion behaviors that conflict with the shell's.)

Tangential observation: The fact that the synopsis shows the arguments ([<path>...]) before the options ([options]) might be better placed the other way around. While the parser will allow arguments and options to be in any order, it's probably more common in usage examples for the arguments to come at the end of the command line.

AArnott commented 2 years ago

As you're testing changes here, please also try with dotnet itself. It's a terrible experience to try to invoke a dotnet console application using dotnet some\path\tomyconsole.dll because one expects they can type part of the path in the argument and press tab, but every time I do that, the entire path is replaced by a switch. I have to literally type the path first and then go back and insert dotnet at the beginning in order for completions to work.