Powershell: Potential improvements to parameter-name tab completions

Created on 31 Jul 2018  路  13Comments  路  Source: PowerShell/PowerShell

Follow-up from #7371.

Substantially revised after initially suggesting (just) alphabetical ordering.

Currently, the order in which the prefix of a parameter name tab-completes if there are multiple matches is seemingly based on the order in which the parameters are declared in the source code (called _declaration order_ below).

The question is whether alternative ordering makes sense, either by default, or via an alternative invocation mechanism.

Environment data

Written as of:

PowerShell Core 6.1.0-preview.4
Issue-Enhancement Resolution-External WG-Engine

All 13 comments

From @rkeithhill https://github.com/PowerShell/PowerShell/issues/7371#issuecomment-408274921

Ooh, might be cool if we had alternate completion orders. One alphabetical and another by most commonly used (or most recently used), etc. Perhaps that is a preference setting or maybe we could switch from the default order using tab / shift+tab to an alternate order using ctrl+tab / ctrl+shift+tab.

From @iSazonov https://github.com/PowerShell/PowerShell/issues/7371#issuecomment-408304828

  1. Get-Help -<Tab> - I'd expect "first most commonly used" order
  2. Get-Help -F<Tab> - I'd expect alphabetical order

We could split cmdlet parameters and common parameters. A cmdlet can has many parameters and we could show only the cmdlet parameters by Tab and common parameters only by Ctrl/Alt-Tab.

@iSazonov

~Can we agree that changing the _current_ tab-completion behavior to alphabetically sorted completions makes sense, irrespective of potential alternative behaviors triggered by different keyboard shortcuts / preference variables?~

~If so, I suggest keeping this issue focused on the former, which should be a straightforward fix that can be implemented quickly.~

~We can then discuss alternative behaviors in a _new_ issue - and that discussion will probable take a while.~

I think we need to understand whether we want to change something, whether we need an alphabetical order or we want something more advanced.

Currently I see alphabetical order in help output and in file completions. So I tend to support the alphabetical order for parameter completions. On the other hand, for some cmdlets, we get secondary, rarely used parameters ahead. On the other hand, we do not have cmdlets with 100 parameters and this makes the consideration not so important.
Also I believe that the introduction of new variables is a superfluous complexity.

I think the declared order is usually most useful and expected, Declared order works well in practice because the most frequently used options tend to get declared first.

Here is an example of someone apparently unhappy with the alphabetic ordering in PowerGUI.

I realize I was exclusively focused on the scenario where the user has already typed a _name prefix_, such as -fo.

Without that, i.e. for the -<tab> scenario, parameter declaration order does make a great deal of sense, if the function/cmdlet is well thought-out; e.g.:

Get-ChildItem -<tab>              # -> Get-ChildItem -Path
Get-ChildItem -Path /foo -<tab>   # -> Get-ChildItem -Path /foo -Filter 

That is, you rely on the parameters to be offered in descending order of importance, without having to think about their names ahead of time.

(Similarly, declaration order makes sense with the PossibleCompletions and the MenuComplete PSReadLine functions; with the latter, you get the best of both worlds: ordering by importance, and the ability filter by typing a prefix.)

By contrast, in the -fo<tab> scenario, the name is foremost on your mind; ideally, there's only one completion, but if there are multiple ones, alphabetical ordering makes more sense to me: you're not looking by importance, you're looking to match a name you're expecting, and alphabetic ordering is a simple and invariant concept; bringing the unrelated dimension of importance into the mix may confuse matters.

Combining these two approaches would amount to a variation of what @iSazonov had in mind to begin with (or is it exactly what you meant all along, @iSazonov? I didn't recognize "first most commonly used" as potentially being the same as declaration order):

  • declaration order for -<tab>
  • alphabetic order for -<prefix><tab>

That said, what would make the distinction moot and would allow us to stick with declaration order consistently is if we could get _realtime feedback_ on what the completion _would_ be, as you're typing, which is what Visual Studio Code already does:

image

You then just need to keep an eye on the currently selected match and keep typing more of the prefix if the right one isn't selected yet - no need to use <tab> to cycle.

Is it possible to bring this type of instant-feedback UI to PSReadLine, @lzybkr?

@mklement0 I did not know this term ("declared order") - this is what I had in mind.

Thanks for clarifying, @iSazonov. I simply adopted @lzybkr's terminology, which I took to mean: declared order = declaration order = the order in which the parameters are declared in the function's/cmdlet's source code.

Thinking about this some more:

I don't think the alphabetic sorting in the case of prefix matching is worth it, after all.
In all likelihood, you'll probably just cycle _until the right parameter name appears_, without even thinking about ordering at all, so whatever the order is, you probably won't pay attention to it or take advantage of it.

The only real improvement I see is from the realtime feedback feature I mentioned. Simply typing without interruption until the right parameter name appears and _then_ tab-completing seems like the best solution to me (again: not sure if we can get that in the terminal).

Incidentally, the good old ISE offers that too, and even throws in _substring_ matching, with prefix matches given precedence:

image

-ou selects the first _prefix_ match (-OutVariable, in common-parameter declaration order, I presume, before -OutBuffer), but also shows _substring_ matches (other parameters that contain ou).

Speaking of declaration order: I haven't looked at other cmdlets, but Get-Content is an example where the order warrants fixing: currently, you get -ReadCount, -TotalCount , and -Tail as the first 3 completions.

I've modified the title and the initial post to make this topic generically about improvements to parameter-name tab-completion.

If no one is interested in continuing this conversation, I'm also happy to close it.

The drop down list is something I'd like to see. I'd think the presentation would be in PSReadLine. Extensibility of parameter ordering should be added to https://github.com/PowerShell/PowerShell-RFC/pull/123

Thanks, @SteveL-MSFT.

Sorry for my piecemeal insights - I should have put more thought into this up front.

The drop down list is something I'd like to see

It's actually easy to get that already, via the aforementioned MenuComplete PSReadLine function (which should have tipped me off that such a UI is indeed possible...):

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

With that in place, when you press Tab:

  • unambiguous prefixes expand instantly, as they do by default.

  • ambiguous ones show a menu akin to a dropdown, whose entries you can cycle through with Tab; a selection is committed with Enter; as a bonus, the _type_ of the currently selected item is shown at the bottom.

image

While this is a great option, especially for discovery of parameters, I wish there were also a more streamlined alternative for power users, where you get _inline previews_ of what the parameter name _would_ complete to _if_ you pressed Tab at that moment.

I've submitted a PSReadLine issue for that - see https://github.com/lzybkr/PSReadLine/issues/741

Plus another one that suggests appending a space to a completion if it can be assumed to form a self-contained argument - see https://github.com/lzybkr/PSReadLine/issues/740

Given the above, I'm closing this.
@rkeithhill, @iSazonov please let me know if you prefer to keep it open, but it sounds like your suggestions should be added to https://github.com/PowerShell/PowerShell-RFC/pull/123, as @SteveL-MSFT suggests.

Comments was moved to the RFC

Was this page helpful?
0 / 5 - 0 ratings