diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java index f43f949..6980334 100644 --- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java +++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java @@ -354,7 +354,7 @@ public class CommandDispatcher { for (final CompletableFuture future : futures) { suggestions.add(future.join()); } - result.complete(Suggestions.merge(suggestions)); + result.complete(Suggestions.merge(parse.getReader().getString(), suggestions)); }); return result; diff --git a/src/main/java/com/mojang/brigadier/context/StringRange.java b/src/main/java/com/mojang/brigadier/context/StringRange.java index f97cdcb..3765bb9 100644 --- a/src/main/java/com/mojang/brigadier/context/StringRange.java +++ b/src/main/java/com/mojang/brigadier/context/StringRange.java @@ -61,4 +61,5 @@ public class StringRange { ", end=" + end + '}'; } + } diff --git a/src/main/java/com/mojang/brigadier/suggestion/Suggestion.java b/src/main/java/com/mojang/brigadier/suggestion/Suggestion.java index 39887b7..ad91c14 100644 --- a/src/main/java/com/mojang/brigadier/suggestion/Suggestion.java +++ b/src/main/java/com/mojang/brigadier/suggestion/Suggestion.java @@ -65,4 +65,19 @@ public class Suggestion implements Comparable { public int compareTo(final Suggestion o) { return text.compareTo(o.text); } + + public String expand(final String command, final StringRange range) { + if (range.equals(this.range)) { + return text; + } + final StringBuilder result = new StringBuilder(); + if (range.getStart() < this.range.getStart()) { + result.append(command.substring(range.getStart(), this.range.getStart())); + } + result.append(text); + if (range.getEnd() > this.range.getEnd()) { + result.append(command.substring(this.range.getEnd(), range.getEnd())); + } + return result.toString(); + } } diff --git a/src/main/java/com/mojang/brigadier/suggestion/Suggestions.java b/src/main/java/com/mojang/brigadier/suggestion/Suggestions.java index 4c9de7b..ffa8f86 100644 --- a/src/main/java/com/mojang/brigadier/suggestion/Suggestions.java +++ b/src/main/java/com/mojang/brigadier/suggestion/Suggestions.java @@ -6,44 +6,28 @@ import com.mojang.brigadier.context.StringRange; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; 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 static final Suggestions EMPTY = new Suggestions(new StringRange(0, 0), Lists.newArrayList()); - private final String input; private final StringRange range; - private final List suggestions; + private final List suggestions; - public Suggestions(final String input, final List suggestions) { - this.input = input; + public Suggestions(final StringRange range, final List suggestions) { + this.range = range; 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 getList() { + public List getList() { return suggestions; } @@ -60,33 +44,60 @@ public class Suggestions { return false; } final Suggestions that = (Suggestions) o; - return Objects.equals(input, that.input) && - Objects.equals(range, that.range) && + return Objects.equals(range, that.range) && Objects.equals(suggestions, that.suggestions); } @Override public int hashCode() { - return Objects.hash(input, range, suggestions); + return Objects.hash(range, suggestions); + } + + @Override + public String toString() { + return "Suggestions{" + + "range=" + range + + ", suggestions=" + suggestions + + '}'; } public static CompletableFuture empty() { return CompletableFuture.completedFuture(EMPTY); } - public static Suggestions merge(final Collection inputs) { - if (inputs.isEmpty()) { + public static Suggestions merge(final String command, final Collection input) { + if (input.isEmpty()) { return EMPTY; - } else if (inputs.size() == 1) { - return inputs.iterator().next(); + } else if (input.size() == 1) { + return input.iterator().next(); } - final Set suggestions = Sets.newHashSet(); - for (final Suggestions input : inputs) { - suggestions.addAll(input.getList()); + final Set texts = new HashSet<>(); + for (final Suggestions suggestions : input) { + for (final String text : suggestions.getList()) { + texts.add(new Suggestion(suggestions.getRange(), text)); + } } - final List sorted = Lists.newArrayList(suggestions); + return create(command, texts); + } + + public static Suggestions create(final String command, final Collection suggestions) { + if (suggestions.isEmpty()) { + return EMPTY; + } + int start = Integer.MAX_VALUE; + int end = Integer.MIN_VALUE; + for (final Suggestion suggestion : suggestions) { + start = Math.min(suggestion.getRange().getStart(), start); + end = Math.max(suggestion.getRange().getEnd(), end); + } + final StringRange range = new StringRange(start, end); + final Set texts = Sets.newHashSet(); + for (final Suggestion suggestion : suggestions) { + texts.add(suggestion.expand(command, range)); + } + final List sorted = Lists.newArrayList(texts); Collections.sort(sorted); - return new Suggestions(inputs.iterator().next().getInput(), sorted); + return new Suggestions(range, sorted); } } diff --git a/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java b/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java index becc7cb..eeb55e7 100644 --- a/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java +++ b/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java @@ -32,11 +32,11 @@ public class SuggestionsBuilder { } public Suggestions build() { - return new Suggestions(input, result); + return Suggestions.create(input, result); } public CompletableFuture buildFuture() { - return CompletableFuture.completedFuture(new Suggestions(input, result)); + return CompletableFuture.completedFuture(build()); } public SuggestionsBuilder suggest(final String text) { diff --git a/src/test/java/com/mojang/brigadier/CommandSuggestionsTest.java b/src/test/java/com/mojang/brigadier/CommandSuggestionsTest.java index 6730c79..a3e3881 100644 --- a/src/test/java/com/mojang/brigadier/CommandSuggestionsTest.java +++ b/src/test/java/com/mojang/brigadier/CommandSuggestionsTest.java @@ -2,7 +2,6 @@ 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; @@ -39,11 +38,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(subject.parse("", source)).join(); assertThat(result.getRange(), equalTo(new StringRange(0, 0))); - 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") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("bar", "baz", "foo"))); } @Test @@ -55,10 +50,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(subject.parse("b", source)).join(); 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") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("ar", "az"))); } @Test @@ -73,11 +65,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(subject.parse("parent ", source)).join(); assertThat(result.getRange(), equalTo(new StringRange(7, 7))); - 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") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("bar", "baz", "foo"))); } @Test @@ -93,10 +81,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(parse).join(); 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") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("ar", "az"))); } @Test @@ -108,9 +93,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(parse).join(); assertThat(result.getRange(), equalTo(new StringRange(9, 9))); - assertThat(result.getList(), equalTo(Lists.newArrayList( - new Suggestion(new StringRange(9, 9), "sub") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("sub"))); } @Test @@ -122,9 +105,7 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(parse).join(); assertThat(result.getRange(), equalTo(new StringRange(10, 10))); - assertThat(result.getList(), equalTo(Lists.newArrayList( - new Suggestion(new StringRange(10, 10), "ub") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("ub"))); } @Test @@ -144,9 +125,7 @@ public class CommandSuggestionsTest { 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.getList(), equalTo(Lists.newArrayList( - new Suggestion(new StringRange(33, 33), "loop") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("loop"))); } @Test @@ -207,9 +186,6 @@ public class CommandSuggestionsTest { final Suggestions result = subject.getCompletionSuggestions(parse).join(); assertThat(result.getRange(), equalTo(new StringRange(18, 18))); - assertThat(result.getList(), equalTo(Lists.newArrayList( - new Suggestion(new StringRange(18, 18), "bar"), - new Suggestion(new StringRange(18, 18), "baz") - ))); + assertThat(result.getList(), equalTo(Lists.newArrayList("bar", "baz"))); } } \ No newline at end of file diff --git a/src/test/java/com/mojang/brigadier/suggestion/SuggestionTest.java b/src/test/java/com/mojang/brigadier/suggestion/SuggestionTest.java index fd2ba07..d43640e 100644 --- a/src/test/java/com/mojang/brigadier/suggestion/SuggestionTest.java +++ b/src/test/java/com/mojang/brigadier/suggestion/SuggestionTest.java @@ -48,4 +48,34 @@ public class SuggestionTest { final Suggestion suggestion = new Suggestion(new StringRange(0, 12), "Oh dear."); assertThat(suggestion.apply("Hello world!"), equalTo("Oh dear.")); } + + @Test + public void expand_unchanged() { + final Suggestion suggestion = new Suggestion(new StringRange(1, 1), "oo"); + assertThat(suggestion.expand("f", new StringRange(1, 1)), equalTo("oo")); + } + + @Test + public void expand_left() { + final Suggestion suggestion = new Suggestion(new StringRange(1, 1), "oo"); + assertThat(suggestion.expand("f", new StringRange(0, 1)), equalTo("foo")); + } + + @Test + public void expand_right() { + final Suggestion suggestion = new Suggestion(new StringRange(0, 0), "minecraft:"); + assertThat(suggestion.expand("fish", new StringRange(0, 4)), equalTo("minecraft:fish")); + } + + @Test + public void expand_both() { + final Suggestion suggestion = new Suggestion(new StringRange(11, 11), "minecraft:"); + assertThat(suggestion.expand("give Steve fish_block", new StringRange(5, 21)), equalTo("Steve minecraft:fish_block")); + } + + @Test + public void expand_replacement() { + final Suggestion suggestion = new Suggestion(new StringRange(6, 11), "strangers"); + assertThat(suggestion.expand("Hello world!", new StringRange(0, 12)), equalTo("Hello strangers!")); + } } \ No newline at end of file diff --git a/src/test/java/com/mojang/brigadier/suggestion/SuggestionsBuilderTest.java b/src/test/java/com/mojang/brigadier/suggestion/SuggestionsBuilderTest.java index 9b0c424..9feceb9 100644 --- a/src/test/java/com/mojang/brigadier/suggestion/SuggestionsBuilderTest.java +++ b/src/test/java/com/mojang/brigadier/suggestion/SuggestionsBuilderTest.java @@ -21,7 +21,7 @@ public class SuggestionsBuilderTest { @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.getList(), equalTo(Lists.newArrayList("orld!"))); assertThat(result.getRange(), equalTo(new StringRange(7, 7))); assertThat(result.isEmpty(), is(false)); } @@ -29,7 +29,7 @@ public class SuggestionsBuilderTest { @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.getList(), equalTo(Lists.newArrayList("everybody"))); assertThat(result.getRange(), equalTo(new StringRange(6, 7))); assertThat(result.isEmpty(), is(false)); } @@ -38,14 +38,13 @@ public class SuggestionsBuilderTest { 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.getList(), equalTo(Lists.newArrayList("everybody", "weekend", "world!"))); assertThat(result.getRange(), equalTo(new StringRange(6, 7))); assertThat(result.isEmpty(), is(false)); } diff --git a/src/test/java/com/mojang/brigadier/suggestion/SuggestionsTest.java b/src/test/java/com/mojang/brigadier/suggestion/SuggestionsTest.java index d376439..a2926a1 100644 --- a/src/test/java/com/mojang/brigadier/suggestion/SuggestionsTest.java +++ b/src/test/java/com/mojang/brigadier/suggestion/SuggestionsTest.java @@ -13,26 +13,22 @@ import static org.junit.Assert.assertThat; public class SuggestionsTest { @Test public void merge_empty() { - final Suggestions merged = Suggestions.merge(Collections.emptyList()); + final Suggestions merged = Suggestions.merge("foo b", 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)); + final Suggestions suggestions = new Suggestions(new StringRange(5, 5), Lists.newArrayList("ar")); + final Suggestions merged = Suggestions.merge("foo b", 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))); + final Suggestions a = new Suggestions(new StringRange(5, 5), Lists.newArrayList("ar", "az")); + final Suggestions b = new Suggestions(new StringRange(4, 5), Lists.newArrayList("foo", "qux", "apple")); + final Suggestions merged = Suggestions.merge("foo b", Lists.newArrayList(a, b)); + assertThat(merged.getList(), equalTo(Lists.newArrayList("apple", "bar", "baz", "foo", "qux"))); } } \ No newline at end of file diff --git a/src/test/java/com/mojang/brigadier/tree/LiteralCommandNodeTest.java b/src/test/java/com/mojang/brigadier/tree/LiteralCommandNodeTest.java index 0e5c246..21212ec 100644 --- a/src/test/java/com/mojang/brigadier/tree/LiteralCommandNodeTest.java +++ b/src/test/java/com/mojang/brigadier/tree/LiteralCommandNodeTest.java @@ -8,9 +8,7 @@ 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; @@ -81,7 +79,7 @@ public class LiteralCommandNodeTest extends AbstractCommandNodeTest { @Test public void testSuggestions() throws Exception { final Suggestions empty = node.listSuggestions(contextBuilder.build(""), new SuggestionsBuilder("", 0)).join(); - assertThat(empty.getList(), equalTo(Lists.newArrayList(new Suggestion(new StringRange(0, 0), "foo")))); + assertThat(empty.getList(), equalTo(Lists.newArrayList("foo"))); final Suggestions foo = node.listSuggestions(contextBuilder.build("foo"), new SuggestionsBuilder("foo", 0)).join(); assertThat(foo.isEmpty(), is(true));