Implement Named Parameters and Per Parameter Tab Completion #178
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
Provides both Named Parameters through the
@Switch
annotation as well as per parameter TabCompletionA parameter can optionally be annotated with
@Switch
to provide one or more names it can be referred by. It can then be used anywhere before its normal position upto and including its normal position by passing "-{switch name} {value}" in the command. It can also be used normally by position as well without the switch name.Due to the nature of how Tab completions work, a Switch MUST use the parameter CommandCompletion annotation to provide tab completions, otherwise it will be assumed to have none in those positions. Method Level CommandCompletion annotations will be respected as well.
Both execution and tab completion use a method parseArgument to ensure both follow the same parsing rules.
Example
This will allow the following to work:
Whilst typing, when a '-' is detected, tab completion will show a completion list of unused switches. This will be reduced as switches are used or the parameters providing the switch are resolved by position. So in the 4th example when starting to type "-player" it will only show "-player" on the tab completion, whereas before typing "-title" it will show both options. In the 6th example when starting to type '-title' it will only show '-title' as player has already been satisfied by position.
After a switch is typed its own command completions will be provided.
Note in the example it will use the
@menulist
tab completion for argument menuitem, and the per parameter ones for the other parameters.How its done
A new method to RegisterdedCommand, parseArgument, is used to take a list of arguments and return the current completion, the list of parameters (in the order detected from the arguments, so not necessarily in proper parameter order), a list of unused switches, and if the current argument is potentially a switch (allows a "-" sign to be used as an argument to a switch without it thinking its a new switch).
Both TabCompletion and Execution use this to resolve the arguments to ensure that both operate the same way.
Reason for requiring Per Parameter Tab Completion
There some challenges to a Switch with tab completion. One of the biggest ones is that an IssuerAwareContext does not have to consume any arguments (For example a Player.class will consume its argument if there is a Flag("other") provided, otherwise it does not), which also means it does not consume tab completions. This makes it impossible to know real time which tab completions to move using position only.
In order to satisfy as many of the requirements for this as possible with fewest changes, the easiest option is to require that a per-parameter tab completion is provided for a Switch.
For example:
it is impossible to know that the
@players
belongs to player2 and not player1 without knowing that a Player context uses a flag to change its behaviour. This means typing '-test', it is hard to know that 'test1|test2' belongs to that parameter.The only option is if parameters were actively involved in tab completion or declared the number of arguments they consume upfront. This is not easy to satsify in a backwards compatible method.
Todo
Maybe a flag to force a switch to be named rather than satisfied by position (IE:
@Switch("option", true)
) with false by default to allow it to satsify either by position or name. I'm not too sure if this is needed or not.Handle
@Optional
and@Default
if it doesn't already work