Implement suggestions for Bukkit + Sponge

This commit is contained in:
Kenzie Togami
2019-05-05 22:06:20 -07:00
committed by Kenzie Togami
parent 1c54a04fd1
commit 8a3e6a12b9
15 changed files with 295 additions and 133 deletions

View File

@ -91,6 +91,7 @@ import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
import com.sk89q.worldedit.internal.command.exception.WorldEditExceptionConverter;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.eventbus.Subscribe;
@ -125,15 +126,14 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
@ -419,34 +419,8 @@ public final class PlatformCommandManager {
dynamicHandler.setHandler(null);
}
public String[] commandDetection(String[] split) {
// Quick script shortcut
if (split[0].matches("^[^/].*\\.js$")) {
String[] newSplit = new String[split.length + 1];
System.arraycopy(split, 0, newSplit, 1, split.length);
newSplit[0] = "cs";
newSplit[1] = newSplit[1];
split = newSplit;
}
String searchCmd = split[0].toLowerCase(Locale.ROOT);
// Try to detect the command
if (!commandManager.containsCommand(searchCmd)) {
if (worldEdit.getConfiguration().noDoubleSlash && commandManager.containsCommand("/" + searchCmd)) {
split[0] = "/" + split[0];
} else if (searchCmd.length() >= 2 && searchCmd.charAt(0) == '/' && commandManager.containsCommand(searchCmd.substring(1))) {
split[0] = split[0].substring(1);
}
}
return split;
}
private String[] parseArgs(String input) {
return commandDetection(new CommandArgParser(input.substring(1))
.parseArgs()
.toArray(String[]::new));
private Stream<Substring> parseArgs(String input) {
return new CommandArgParser(CommandArgParser.spaceSplit(input.substring(1))).parseArgs();
}
@Subscribe
@ -454,7 +428,9 @@ public final class PlatformCommandManager {
Request.reset();
Actor actor = platformManager.createProxyActor(event.getActor());
String[] split = parseArgs(event.getArguments());
String[] split = parseArgs(event.getArguments())
.map(Substring::getSubstring)
.toArray(String[]::new);
// No command found!
if (!commandManager.containsCommand(split[0])) {
@ -581,13 +557,26 @@ public final class PlatformCommandManager {
@Subscribe
public void handleCommandSuggestion(CommandSuggestionEvent event) {
try {
String[] split = parseArgs(event.getArguments());
MemoizingValueAccess access = initializeInjectedValues(event::getArguments, event.getActor());
ImmutableSet<Suggestion> suggestions = commandManager.getSuggestions(access, Arrays.asList(split));
String arguments = event.getArguments();
List<Substring> split = parseArgs(arguments).collect(Collectors.toList());
List<String> argStrings = split.stream()
.map(Substring::getSubstring)
.collect(Collectors.toList());
MemoizingValueAccess access = initializeInjectedValues(() -> arguments, event.getActor());
ImmutableSet<Suggestion> suggestions = commandManager.getSuggestions(access, argStrings);
log.debug("For input: {}", event.getArguments());
log.debug("I would suggest this: {}", suggestions);
// TODO send back suggestions
event.setSuggestions(suggestions.stream()
.map(suggestion -> {
Substring original = suggestion.getReplacedArgument() == split.size()
? Substring.from(arguments, arguments.length() - 1)
: split.get(suggestion.getReplacedArgument());
// increase original points by 1, for removed `/` in `parseArgs`
return Substring.wrap(
suggestion.getSuggestion(),
original.getStart() + 1,
original.getEnd() + 1
);
}).collect(Collectors.toList()));
} catch (CommandException e) {
event.getActor().printError(e.getMessage());
}