Skip to content

Commit

Permalink
New suggestion API
Browse files Browse the repository at this point in the history
  • Loading branch information
Dinnerbone committed Nov 20, 2017
1 parent 557352f commit 095498c
Show file tree
Hide file tree
Showing 21 changed files with 494 additions and 150 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import groovy.io.FileType
apply plugin: 'java-library'
apply plugin: 'maven'

version = '0.1.11'
version = '0.1.13'
group = 'com.mojang'

task wrapper(type: Wrapper) {
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/com/mojang/brigadier/CommandDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
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;
Expand Down Expand Up @@ -310,7 +312,7 @@ private String getSmartUsage(final CommandNode<S> node, final S source, final bo
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;
Expand All @@ -336,25 +338,23 @@ public CompletableFuture<CommandSuggestions> getCompletionSuggestions(final Pars
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;
Expand Down
55 changes: 0 additions & 55 deletions src/main/java/com/mojang/brigadier/CommandSuggestions.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
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();
}
}
20 changes: 8 additions & 12 deletions src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java
Original file line number Diff line number Diff line change
@@ -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> {
Expand All @@ -28,16 +27,13 @@ public <S> Boolean parse(final StringReader reader, final CommandContextBuilder<
}

@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();
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -19,12 +19,12 @@ public static <S, T> RequiredArgumentBuilder<S, T> argument(final String name, f
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;
}

Expand Down
68 changes: 68 additions & 0 deletions src/main/java/com/mojang/brigadier/suggestion/Suggestion.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
92 changes: 92 additions & 0 deletions src/main/java/com/mojang/brigadier/suggestion/Suggestions.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading

0 comments on commit 095498c

Please sign in to comment.