New suggestion API
This commit is contained in:
@@ -11,6 +11,8 @@ import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
@@ -310,7 +312,7 @@ public class CommandDispatcher<S> {
|
||||
return self;
|
||||
}
|
||||
|
||||
public CompletableFuture<CommandSuggestions> getCompletionSuggestions(final ParseResults<S> parse) {
|
||||
public CompletableFuture<Suggestions> getCompletionSuggestions(final ParseResults<S> parse) {
|
||||
final CommandContextBuilder<S> rootContext = parse.getContext();
|
||||
final CommandContextBuilder<S> context = rootContext.getLastChild();
|
||||
final CommandNode<S> parent;
|
||||
@@ -336,25 +338,23 @@ public class CommandDispatcher<S> {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") final CompletableFuture<Collection<String>>[] futures = new CompletableFuture[parent.getChildren().size()];
|
||||
@SuppressWarnings("unchecked") final CompletableFuture<Suggestions>[] futures = new CompletableFuture[parent.getChildren().size()];
|
||||
int i = 0;
|
||||
for (final CommandNode<S> node : parent.getChildren()) {
|
||||
try {
|
||||
futures[i++] = node.listSuggestions(context.build(parse.getReader().getString()), parse.getReader().getString().substring(start));
|
||||
futures[i++] = node.listSuggestions(context.build(parse.getReader().getString()), new SuggestionsBuilder(parse.getReader().getString(), start));
|
||||
} catch (final CommandSyntaxException e) {
|
||||
futures[i++] = CompletableFuture.completedFuture(Collections.emptyList());
|
||||
futures[i++] = Suggestions.empty();
|
||||
}
|
||||
}
|
||||
|
||||
final CompletableFuture<CommandSuggestions> result = new CompletableFuture<>();
|
||||
final CompletableFuture<Suggestions> result = new CompletableFuture<>();
|
||||
CompletableFuture.allOf(futures).thenRun(() -> {
|
||||
final Set<String> suggestions = Sets.newHashSet();
|
||||
for (final CompletableFuture<Collection<String>> future : futures) {
|
||||
suggestions.addAll(future.join());
|
||||
final List<Suggestions> suggestions = Lists.newArrayList();
|
||||
for (final CompletableFuture<Suggestions> future : futures) {
|
||||
suggestions.add(future.join());
|
||||
}
|
||||
final List<String> sorted = new ArrayList<>(suggestions);
|
||||
Collections.sort(sorted);
|
||||
result.complete(new CommandSuggestions(new StringRange(start, parse.getReader().getTotalLength()), sorted));
|
||||
result.complete(Suggestions.merge(suggestions));
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package com.mojang.brigadier;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class CommandSuggestions {
|
||||
private final StringRange range;
|
||||
private final List<String> suggestions;
|
||||
|
||||
public CommandSuggestions(final StringRange range, final List<String> suggestions) {
|
||||
this.range = range;
|
||||
this.suggestions = suggestions;
|
||||
}
|
||||
|
||||
public StringRange getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public List<String> getSuggestions() {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof CommandSuggestions)) {
|
||||
return false;
|
||||
}
|
||||
final CommandSuggestions that = (CommandSuggestions) o;
|
||||
return Objects.equals(range, that.range) && Objects.equals(suggestions, that.suggestions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(range, suggestions);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return suggestions.isEmpty();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Provider<S> {
|
||||
CompletableFuture<Collection<String>> getSuggestions(final CommandContext<S> context, final String prefix) throws CommandSyntaxException;
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,15 @@ import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface ArgumentType<T> {
|
||||
<S> T parse(StringReader reader, CommandContextBuilder<S> contextBuilder) throws CommandSyntaxException;
|
||||
|
||||
default <S> CompletableFuture<Collection<String>> listSuggestions(final CommandContext<S> context, final String command) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
default <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
return Suggestions.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.mojang.brigadier.arguments;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BoolArgumentType implements ArgumentType<Boolean> {
|
||||
@@ -28,16 +27,13 @@ public class BoolArgumentType implements ArgumentType<Boolean> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Collection<String>> listSuggestions(final CommandContext<S> context, final String command) {
|
||||
final List<String> result = Lists.newArrayList();
|
||||
|
||||
if ("true".startsWith(command)) {
|
||||
result.add("true");
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
if ("true".startsWith(builder.getRemaining().toLowerCase())) {
|
||||
builder.suggest("true");
|
||||
}
|
||||
if ("false".startsWith(command)) {
|
||||
result.add("false");
|
||||
if ("false".startsWith(builder.getRemaining().toLowerCase())) {
|
||||
builder.suggest("false");
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(result);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.mojang.brigadier.builder;
|
||||
|
||||
import com.mojang.brigadier.CommandSuggestions;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.tree.ArgumentCommandNode;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
|
||||
public class RequiredArgumentBuilder<S, T> extends ArgumentBuilder<S, RequiredArgumentBuilder<S, T>> {
|
||||
private final String name;
|
||||
private final ArgumentType<T> type;
|
||||
private CommandSuggestions.Provider<S> suggestionsProvider = null;
|
||||
private SuggestionProvider<S> suggestionsProvider = null;
|
||||
|
||||
private RequiredArgumentBuilder(final String name, final ArgumentType<T> type) {
|
||||
this.name = name;
|
||||
@@ -19,12 +19,12 @@ public class RequiredArgumentBuilder<S, T> extends ArgumentBuilder<S, RequiredAr
|
||||
return new RequiredArgumentBuilder<>(name, type);
|
||||
}
|
||||
|
||||
public RequiredArgumentBuilder<S, T> suggests(final CommandSuggestions.Provider<S> provider) {
|
||||
public RequiredArgumentBuilder<S, T> suggests(final SuggestionProvider<S> provider) {
|
||||
this.suggestionsProvider = provider;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public CommandSuggestions.Provider<S> getSuggestionsProvider() {
|
||||
public SuggestionProvider<S> getSuggestionsProvider() {
|
||||
return suggestionsProvider;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Suggestion implements Comparable<Suggestion> {
|
||||
private final StringRange range;
|
||||
private final String text;
|
||||
|
||||
public Suggestion(final StringRange range, final String text) {
|
||||
this.range = range;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public StringRange getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String apply(final String input) {
|
||||
if (range.getStart() == 0 && range.getEnd() == input.length()) {
|
||||
return text;
|
||||
}
|
||||
final StringBuilder result = new StringBuilder();
|
||||
if (range.getStart() > 0) {
|
||||
result.append(input.substring(0, range.getStart()));
|
||||
}
|
||||
result.append(text);
|
||||
if (range.getEnd() < input.length()) {
|
||||
result.append(input.substring(range.getEnd()));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Suggestion)) {
|
||||
return false;
|
||||
}
|
||||
final Suggestion that = (Suggestion) o;
|
||||
return Objects.equals(range, that.range) && Objects.equals(text, that.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(range, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Suggestion{" +
|
||||
"range=" + range +
|
||||
", text='" + text + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Suggestion o) {
|
||||
return text.compareTo(o.text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SuggestionProvider<S> {
|
||||
CompletableFuture<Suggestions> getSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) throws CommandSyntaxException;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Suggestions {
|
||||
private static final Suggestions EMPTY = new Suggestions("", Lists.newArrayList());
|
||||
|
||||
private final String input;
|
||||
private final StringRange range;
|
||||
private final List<Suggestion> suggestions;
|
||||
|
||||
public Suggestions(final String input, final List<Suggestion> suggestions) {
|
||||
this.input = input;
|
||||
this.suggestions = suggestions;
|
||||
|
||||
if (suggestions.isEmpty()) {
|
||||
range = new StringRange(input.length(), input.length());
|
||||
} else {
|
||||
int start = Integer.MAX_VALUE;
|
||||
int end = Integer.MIN_VALUE;
|
||||
for (final Suggestion suggestion : suggestions) {
|
||||
start = Math.min(start, suggestion.getRange().getStart());
|
||||
end = Math.max(end, suggestion.getRange().getEnd());
|
||||
}
|
||||
range = new StringRange(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public StringRange getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public List<Suggestion> getList() {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return suggestions.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Suggestions)) {
|
||||
return false;
|
||||
}
|
||||
final Suggestions that = (Suggestions) o;
|
||||
return Objects.equals(input, that.input) &&
|
||||
Objects.equals(range, that.range) &&
|
||||
Objects.equals(suggestions, that.suggestions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(input, range, suggestions);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Suggestions> empty() {
|
||||
return CompletableFuture.completedFuture(EMPTY);
|
||||
}
|
||||
|
||||
public static Suggestions merge(final Collection<Suggestions> inputs) {
|
||||
if (inputs.isEmpty()) {
|
||||
return EMPTY;
|
||||
} else if (inputs.size() == 1) {
|
||||
return inputs.iterator().next();
|
||||
}
|
||||
|
||||
final Set<Suggestion> suggestions = Sets.newHashSet();
|
||||
for (final Suggestions input : inputs) {
|
||||
suggestions.addAll(input.getList());
|
||||
}
|
||||
final List<Suggestion> sorted = Lists.newArrayList(suggestions);
|
||||
Collections.sort(sorted);
|
||||
return new Suggestions(inputs.iterator().next().getInput(), sorted);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class SuggestionsBuilder {
|
||||
private final String input;
|
||||
private final int start;
|
||||
private final String remaining;
|
||||
private final List<Suggestion> result = new ArrayList<>();
|
||||
|
||||
public SuggestionsBuilder(final String input, final int start) {
|
||||
this.input = input;
|
||||
this.start = start;
|
||||
this.remaining = input.substring(start);
|
||||
}
|
||||
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public String getRemaining() {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
public Suggestions build() {
|
||||
return new Suggestions(input, result);
|
||||
}
|
||||
|
||||
public CompletableFuture<Suggestions> buildFuture() {
|
||||
return CompletableFuture.completedFuture(new Suggestions(input, result));
|
||||
}
|
||||
|
||||
public SuggestionsBuilder suggest(final String text) {
|
||||
if (text.equals(remaining)) {
|
||||
return this;
|
||||
}
|
||||
final String prefix = Strings.commonPrefix(text, remaining);
|
||||
result.add(new Suggestion(new StringRange(start + prefix.length(), input.length()), text.substring(prefix.length())));
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuggestionsBuilder restart() {
|
||||
return new SuggestionsBuilder(input, start);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.mojang.brigadier.tree;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandSuggestions;
|
||||
import com.mojang.brigadier.RedirectModifier;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
@@ -10,8 +9,10 @@ import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.context.ParsedArgument;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -21,9 +22,9 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
|
||||
|
||||
private final String name;
|
||||
private final ArgumentType<T> type;
|
||||
private final CommandSuggestions.Provider<S> customSuggestions;
|
||||
private final SuggestionProvider<S> customSuggestions;
|
||||
|
||||
public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final CommandSuggestions.Provider<S> customSuggestions) {
|
||||
public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final SuggestionProvider<S> customSuggestions) {
|
||||
super(command, requirement, redirect, modifier);
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
@@ -44,7 +45,7 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
|
||||
return USAGE_ARGUMENT_OPEN + name + USAGE_ARGUMENT_CLOSE;
|
||||
}
|
||||
|
||||
public CommandSuggestions.Provider<S> getCustomSuggestions() {
|
||||
public SuggestionProvider<S> getCustomSuggestions() {
|
||||
return customSuggestions;
|
||||
}
|
||||
|
||||
@@ -59,11 +60,11 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Collection<String>> listSuggestions(final CommandContext<S> context, final String command) throws CommandSyntaxException {
|
||||
public CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
if (customSuggestions == null) {
|
||||
return type.listSuggestions(context, command);
|
||||
return type.listSuggestions(context, builder);
|
||||
} else {
|
||||
return customSuggestions.getSuggestions(context, command);
|
||||
return customSuggestions.getSuggestions(context, builder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -104,7 +106,7 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
||||
|
||||
public abstract void parse(StringReader reader, CommandContextBuilder<S> contextBuilder) throws CommandSyntaxException;
|
||||
|
||||
public abstract CompletableFuture<Collection<String>> listSuggestions(CommandContext<S> context, String command) throws CommandSyntaxException;
|
||||
public abstract CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) throws CommandSyntaxException;
|
||||
|
||||
public abstract ArgumentBuilder<S, ?> createBuilder();
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -50,11 +50,11 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Collection<String>> listSuggestions(final CommandContext<S> context, final String command) {
|
||||
if (literal.toLowerCase().startsWith(command.toLowerCase())) {
|
||||
return CompletableFuture.completedFuture(Collections.singleton(literal));
|
||||
public CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
if (literal.toLowerCase().startsWith(builder.getRemaining().toLowerCase())) {
|
||||
return builder.suggest(literal).buildFuture();
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
return Suggestions.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -30,8 +31,8 @@ public class RootCommandNode<S> extends CommandNode<S> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Collection<String>> listSuggestions(CommandContext<S> context, final String command) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
public CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
return Suggestions.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.mojang.brigadier;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -14,6 +16,7 @@ import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
||||
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
||||
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -33,10 +36,14 @@ public class CommandSuggestionsTest {
|
||||
subject.register(literal("bar"));
|
||||
subject.register(literal("baz"));
|
||||
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("", source)).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(subject.parse("", source)).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(0, 0)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz", "foo")));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(0, 0), "bar"),
|
||||
new Suggestion(new StringRange(0, 0), "baz"),
|
||||
new Suggestion(new StringRange(0, 0), "foo")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -45,10 +52,13 @@ public class CommandSuggestionsTest {
|
||||
subject.register(literal("bar"));
|
||||
subject.register(literal("baz"));
|
||||
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("b", source)).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(subject.parse("b", source)).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(0, 1)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz")));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(1, 1)));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(1, 1), "ar"),
|
||||
new Suggestion(new StringRange(1, 1), "az")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,10 +70,14 @@ public class CommandSuggestionsTest {
|
||||
.then(literal("baz"))
|
||||
);
|
||||
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("parent ", source)).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(subject.parse("parent ", source)).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(7, 7)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz", "foo")));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(7, 7), "bar"),
|
||||
new Suggestion(new StringRange(7, 7), "baz"),
|
||||
new Suggestion(new StringRange(7, 7), "foo")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,10 +90,13 @@ public class CommandSuggestionsTest {
|
||||
);
|
||||
|
||||
final ParseResults<Object> parse = subject.parse("parent b", source);
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(7, 8)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz")));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(8, 8)));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(8, 8), "ar"),
|
||||
new Suggestion(new StringRange(8, 8), "az")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,10 +105,12 @@ public class CommandSuggestionsTest {
|
||||
subject.register(literal("redirect").redirect(actual));
|
||||
|
||||
final ParseResults<Object> parse = subject.parse("redirect ", source);
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(9, 9)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("sub")));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(9, 9), "sub")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,10 +119,12 @@ public class CommandSuggestionsTest {
|
||||
subject.register(literal("redirect").redirect(actual));
|
||||
|
||||
final ParseResults<Object> parse = subject.parse("redirect s", source);
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(9, 10)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("sub")));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(10, 10)));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(10, 10), "ub")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -120,10 +141,12 @@ public class CommandSuggestionsTest {
|
||||
)
|
||||
);
|
||||
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(subject.parse("redirect loop 1 loop 02 loop 003 ", source)).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(subject.parse("redirect loop 1 loop 02 loop 003 ", source)).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(33, 33)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("loop")));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(33, 33), "loop")
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,10 +175,9 @@ public class CommandSuggestionsTest {
|
||||
);
|
||||
|
||||
final ParseResults<Object> parse = subject.parse("execute as Dinnerbone as", source);
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(22, 24)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("as")));
|
||||
assertThat(result.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,9 +204,12 @@ public class CommandSuggestionsTest {
|
||||
);
|
||||
|
||||
final ParseResults<Object> parse = subject.parse("execute as bar as ", source);
|
||||
final CommandSuggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
final Suggestions result = subject.getCompletionSuggestions(parse).join();
|
||||
|
||||
assertThat(result.getRange(), equalTo(new StringRange(18, 18)));
|
||||
assertThat(result.getSuggestions(), equalTo(Lists.newArrayList("bar", "baz")));
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(
|
||||
new Suggestion(new StringRange(18, 18), "bar"),
|
||||
new Suggestion(new StringRange(18, 18), "baz")
|
||||
)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class SuggestionTest {
|
||||
@Test
|
||||
public void apply_insertation_start() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(0, 0), "And so I said: ");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("And so I said: Hello world!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_insertation_middle() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(6, 6), "small ");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("Hello small world!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_insertation_end() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(5, 5), " world!");
|
||||
assertThat(suggestion.apply("Hello"), equalTo("Hello world!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_replacement_start() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(0, 5), "Goodbye");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("Goodbye world!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_replacement_middle() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(6, 11), "Alex");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("Hello Alex!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_replacement_end() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(6, 12), "Creeper!");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("Hello Creeper!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apply_replacement_everything() {
|
||||
final Suggestion suggestion = new Suggestion(new StringRange(0, 12), "Oh dear.");
|
||||
assertThat(suggestion.apply("Hello world!"), equalTo("Oh dear."));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class SuggestionsBuilderTest {
|
||||
private SuggestionsBuilder builder;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
builder = new SuggestionsBuilder("Hello w", 6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggest_appends() {
|
||||
final Suggestions result = builder.suggest("world!").build();
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(new Suggestion(new StringRange(7, 7), "orld!"))));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(7, 7)));
|
||||
assertThat(result.isEmpty(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggest_replaces() {
|
||||
final Suggestions result = builder.suggest("everybody").build();
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(new Suggestion(new StringRange(6, 7), "everybody"))));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(6, 7)));
|
||||
assertThat(result.isEmpty(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggest_noop() {
|
||||
final Suggestions result = builder.suggest("w").build();
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList()));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(7, 7)));
|
||||
assertThat(result.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void suggest_multiple() {
|
||||
final Suggestions result = builder.suggest("world!").suggest("everybody").suggest("weekend").build();
|
||||
assertThat(result.getList(), equalTo(Lists.newArrayList(new Suggestion(new StringRange(7, 7), "orld!"), new Suggestion(new StringRange(6, 7), "everybody"), new Suggestion(new StringRange(7, 7), "eekend"))));
|
||||
assertThat(result.getRange(), equalTo(new StringRange(6, 7)));
|
||||
assertThat(result.isEmpty(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restart() {
|
||||
builder.suggest("won't be included in restart");
|
||||
final SuggestionsBuilder other = builder.restart();
|
||||
assertThat(other, is(not(builder)));
|
||||
assertThat(other.getInput(), equalTo(builder.getInput()));
|
||||
assertThat(other.getStart(), is(builder.getStart()));
|
||||
assertThat(other.getRemaining(), equalTo(builder.getRemaining()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.mojang.brigadier.suggestion;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class SuggestionsTest {
|
||||
@Test
|
||||
public void merge_empty() {
|
||||
final Suggestions merged = Suggestions.merge(Collections.emptyList());
|
||||
assertThat(merged.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void merge_single() {
|
||||
final Suggestions suggestions = new Suggestions("", Lists.newArrayList(new Suggestion(new StringRange(0, 0), "foo")));
|
||||
final Suggestions merged = Suggestions.merge(Collections.singleton(suggestions));
|
||||
assertThat(merged, equalTo(suggestions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void merge_multiple() {
|
||||
final Suggestion foo = new Suggestion(new StringRange(0, 0), "foo");
|
||||
final Suggestion bar = new Suggestion(new StringRange(0, 0), "bar");
|
||||
final Suggestion baz = new Suggestion(new StringRange(0, 0), "baz");
|
||||
final Suggestion qux = new Suggestion(new StringRange(0, 0), "qux");
|
||||
final Suggestions a = new Suggestions("", Lists.newArrayList(foo, bar));
|
||||
final Suggestions b = new Suggestions("", Lists.newArrayList(baz, qux));
|
||||
final Suggestions merged = Suggestions.merge(Lists.newArrayList(a, b));
|
||||
assertThat(merged.getList(), equalTo(Lists.newArrayList(bar, baz, foo, qux)));
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,14 @@ import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -50,8 +48,8 @@ public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
|
||||
|
||||
@Test
|
||||
public void testSuggestions() throws Exception {
|
||||
final Collection<String> result = node.listSuggestions(contextBuilder.build(""), "").join();
|
||||
assertThat(result, is(empty()));
|
||||
final Suggestions result = node.listSuggestions(contextBuilder.build(""), new SuggestionsBuilder("", 0)).join();
|
||||
assertThat(result.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package com.mojang.brigadier.tree;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.testing.EqualsTester;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -79,17 +80,17 @@ public class LiteralCommandNodeTest extends AbstractCommandNodeTest {
|
||||
|
||||
@Test
|
||||
public void testSuggestions() throws Exception {
|
||||
final Collection<String> empty = node.listSuggestions(contextBuilder.build(""), "").join();
|
||||
assertThat(empty, equalTo(Sets.newHashSet("foo")));
|
||||
final Suggestions empty = node.listSuggestions(contextBuilder.build(""), new SuggestionsBuilder("", 0)).join();
|
||||
assertThat(empty.getList(), equalTo(Lists.newArrayList(new Suggestion(new StringRange(0, 0), "foo"))));
|
||||
|
||||
final Collection<String> foo = node.listSuggestions(contextBuilder.build("foo"), "foo").join();
|
||||
assertThat(foo, equalTo(Sets.newHashSet("foo")));
|
||||
final Suggestions foo = node.listSuggestions(contextBuilder.build("foo"), new SuggestionsBuilder("foo", 0)).join();
|
||||
assertThat(foo.isEmpty(), is(true));
|
||||
|
||||
final Collection<String> food = node.listSuggestions(contextBuilder.build("food"), "food").join();
|
||||
assertThat(food, is(empty()));
|
||||
final Suggestions food = node.listSuggestions(contextBuilder.build("food"), new SuggestionsBuilder("food", 0)).join();
|
||||
assertThat(food.isEmpty(), is(true));
|
||||
|
||||
final Collection<String> b = node.listSuggestions(contextBuilder.build("b"), "b").join();
|
||||
assertThat(b, is(empty()));
|
||||
final Suggestions b = node.listSuggestions(contextBuilder.build("b"), new SuggestionsBuilder("b", 0)).join();
|
||||
assertThat(food.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -5,13 +5,12 @@ import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -49,8 +48,8 @@ public class RootCommandNodeTest extends AbstractCommandNodeTest {
|
||||
@Test
|
||||
public void testSuggestions() throws Exception {
|
||||
final CommandContext<Object> context = mock(CommandContext.class);
|
||||
final Collection<String> result = node.listSuggestions(context, "").join();
|
||||
assertThat(result, is(empty()));
|
||||
final Suggestions result = node.listSuggestions(context, new SuggestionsBuilder("", 0)).join();
|
||||
assertThat(result.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
|
||||
Reference in New Issue
Block a user