Waterfall/BungeeCord-Patches/0047-Add-console-command-completion.patch
Minecrell d3dc2d3748 Implement full console command completion
Drop the original console command completion patch and rewrite it
for JLine 3. Add support to complete command names instead of just
command arguments.

The additional single thread executor for command completion was
dropped because it's redundant: since the command completer needs
to wait for it to complete anyway, we might as well do the completion
directly from the console thread.
2017-09-26 19:37:34 +01:00

107 lines
4.2 KiB
Diff

From a40f6085c979862514bde11a195f2c398d90bc37 Mon Sep 17 00:00:00 2001
From: Minecrell <dev@minecrell.net>
Date: Tue, 26 Sep 2017 18:59:37 +0200
Subject: [PATCH] Add console command completion
Register command completer for JLine to complete command names and
command arguments (if supported).
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
index 520ee315..302981d0 100644
--- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
@@ -181,6 +181,41 @@ public class PluginManager
return true;
}
+ // Waterfall start - Add method to tab-complete command names
+ /**
+ * Searches for tab-complete suggestions for the given command line.
+ *
+ * <p>This is similar to {@link #dispatchCommand(CommandSender, String, List)}
+ * called with a list, but it also handles completing the command names itself
+ * instead of just the arguments.</p>
+ *
+ * @param sender The command sender
+ * @param commandLine The current command line
+ * @return The tab-complete suggestions
+ */
+ public List<String> tabCompleteCommand(CommandSender sender, String commandLine) {
+ List<String> suggestions = new java.util.ArrayList<>();
+
+ if (commandLine.indexOf(' ') == -1) {
+ // Complete command name
+ for (Command command : this.commandMap.values()) {
+ if (command.getName().startsWith(commandLine)) {
+ // Check command permissions before adding it to the suggestions
+ String permission = command.getPermission();
+ if (permission == null || permission.isEmpty() || sender.hasPermission(permission)) {
+ suggestions.add(command.getName());
+ }
+ }
+ }
+ } else {
+ // Complete command arguments
+ dispatchCommand(sender, commandLine, suggestions);
+ }
+
+ return suggestions;
+ }
+ // Waterfall end
+
/**
* Returns the {@link Plugin} objects corresponding to all loaded plugins.
*
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/console/ConsoleCommandCompleter.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/console/ConsoleCommandCompleter.java
new file mode 100644
index 00000000..bfcb6e9f
--- /dev/null
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/console/ConsoleCommandCompleter.java
@@ -0,0 +1,31 @@
+package io.github.waterfallmc.waterfall.console;
+
+import net.md_5.bungee.api.ProxyServer;
+import org.jline.reader.Candidate;
+import org.jline.reader.Completer;
+import org.jline.reader.LineReader;
+import org.jline.reader.ParsedLine;
+
+import java.util.List;
+
+final class ConsoleCommandCompleter implements Completer {
+
+ private final ProxyServer proxy;
+
+ ConsoleCommandCompleter(ProxyServer proxy) {
+ this.proxy = proxy;
+ }
+
+ @Override
+ public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
+ List<String> suggestions = this.proxy.getPluginManager().tabCompleteCommand(this.proxy.getConsole(), line.line());
+ if (suggestions.isEmpty()) {
+ return;
+ }
+
+ for (String suggestion : suggestions) {
+ candidates.add(new Candidate(suggestion));
+ }
+ }
+
+}
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/console/WaterfallConsole.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/console/WaterfallConsole.java
index a8a94749..ea52c674 100644
--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/console/WaterfallConsole.java
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/console/WaterfallConsole.java
@@ -51,6 +51,7 @@ public final class WaterfallConsole {
final LineReader reader = LineReaderBuilder.builder()
.appName(ProxyServer.getInstance().getName())
.terminal(terminal)
+ .completer(new ConsoleCommandCompleter(bungee))
.build();
reader.unsetOpt(LineReader.Option.INSERT_TAB);
--
2.14.1