Allow greedy parsers to suggest after a space (#414)

This commit is contained in:
Pablo Herrera 2022-12-13 17:19:16 +01:00 committed by Jason
parent 99d388b708
commit bde084c14b
3 changed files with 61 additions and 8 deletions

View file

@ -629,15 +629,16 @@ public final class CommandTree<C> {
if (commandQueue.isEmpty()) {
return Collections.emptyList();
} else if (child.isLeaf() && commandQueue.size() < 2) {
return this.directSuggestions(commandContext, child, commandQueue.peek());
} else if (child.isLeaf()) {
if (child.getValue() instanceof CompoundArgument) {
final String last = ((LinkedList<String>) commandQueue).getLast();
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, last);
final String input;
if (commandQueue.size() == 1) {
input = commandQueue.peek();
} else {
input = child.getValue() instanceof CompoundArgument
? ((LinkedList<String>) commandQueue).getLast()
: String.join(" ", commandQueue);
}
return Collections.emptyList();
return this.directSuggestions(commandContext, child, input);
} else if (commandQueue.peek().isEmpty()) {
return this.directSuggestions(commandContext, child, commandQueue.peek());
}

View file

@ -30,6 +30,7 @@ import cloud.commandframework.arguments.standard.EnumArgument;
import cloud.commandframework.arguments.standard.IntegerArgument;
import cloud.commandframework.arguments.standard.StringArgument;
import cloud.commandframework.arguments.standard.StringArrayArgument;
import cloud.commandframework.execution.FilteringCommandSuggestionProcessor;
import cloud.commandframework.types.tuples.Pair;
import cloud.commandframework.types.tuples.Triplet;
import java.util.Arrays;
@ -511,6 +512,38 @@ public class CommandSuggestionsTest {
assertThat(suggestions6).isEmpty();
}
@Test
void testGreedyArgumentSuggestsAfterSpace() {
// Arrange
final CommandManager<TestCommandSender> manager = createManager();
manager.command(
manager.commandBuilder("command")
.argument(
StringArgument.<TestCommandSender>newBuilder("string")
.greedy()
.withSuggestionsProvider((context, input) -> Collections.singletonList("hello world"))
.build())
);
manager.commandSuggestionProcessor(
new FilteringCommandSuggestionProcessor<>(
FilteringCommandSuggestionProcessor.Filter.<TestCommandSender>startsWith(true).andTrimBeforeLastSpace()));
// Act
final List<String> suggestions1 = suggest(manager, "command ");
final List<String> suggestions2 = suggest(manager, "command hello");
final List<String> suggestions3 = suggest(manager, "command hello ");
final List<String> suggestions4 = suggest(manager, "command hello wo");
final List<String> suggestions5 = suggest(manager, "command hello world");
final List<String> suggestions6 = suggest(manager, "command hello world ");
// Assert
assertThat(suggestions1).containsExactly("hello world");
assertThat(suggestions2).containsExactly("hello world");
assertThat(suggestions3).containsExactly("world");
assertThat(suggestions4).containsExactly("world");
assertThat(suggestions5).containsExactly("world");
assertThat(suggestions6).isEmpty();
}
@Test
void testFlagYieldingGreedyStringWithLiberalFlagArgument() {