Did someone say console command completion? These commits were authored by @quickwango and come from Bukkit/Bukkit#868 and Bukkit/CraftBukkit#1151

This commit is contained in:
md_5 2013-07-06 09:40:00 +10:00
parent 87854c51ab
commit cd02250065
2 changed files with 167 additions and 0 deletions

View File

@ -0,0 +1,78 @@
From e0673d1050250f5e32ac173a12b3c65cab315b40 Mon Sep 17 00:00:00 2001
From: Phillip Schichtel <quick_wango@code-infection.de>
Date: Mon, 29 Apr 2013 23:07:42 +0200
Subject: [PATCH] Console Command Completion
Implement command tab completion in the console. Adds BUKKIT-4168
To accomplish this 2 changes to Bukkit were required:
- the player check in Command.tabComplete() had to be removed
- the SimpleCommandMap prepends the / only for players
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
index 5416c71..2f189ca 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -78,18 +78,13 @@ public abstract class Command {
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
- if (!(sender instanceof Player) || args.length == 0) {
- return ImmutableList.of();
- }
-
String lastWord = args[args.length - 1];
- Player senderPlayer = (Player) sender;
-
ArrayList<String> matchedPlayers = new ArrayList<String>();
+ final boolean noPlayer = !(sender instanceof Player);
for (Player player : sender.getServer().getOnlinePlayers()) {
String name = player.getName();
- if (senderPlayer.canSee(player) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
+ if (noPlayer || ((Player) sender).canSee(player) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
matchedPlayers.add(name);
}
}
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
index df5f6ef..4c3e421 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -16,6 +16,7 @@ import java.util.regex.Pattern;
import org.apache.commons.lang.Validate;
import org.bukkit.Server;
import org.bukkit.command.defaults.*;
+import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
public class SimpleCommandMap implements CommandMap {
@@ -224,6 +225,8 @@ public class SimpleCommandMap implements CommandMap {
ArrayList<String> completions = new ArrayList<String>();
Map<String, Command> knownCommands = this.knownCommands;
+ final String prefix = (sender instanceof Player ? "/" : "");
+
for (VanillaCommand command : fallbackCommands) {
String name = command.getName();
@@ -239,7 +242,7 @@ public class SimpleCommandMap implements CommandMap {
continue;
}
- completions.add('/' + name);
+ completions.add(prefix + name);
}
for (Map.Entry<String, Command> commandEntry : knownCommands.entrySet()) {
@@ -252,7 +255,7 @@ public class SimpleCommandMap implements CommandMap {
String name = commandEntry.getKey(); // Use the alias, not command name
if (StringUtil.startsWithIgnoreCase(name, cmdLine)) {
- completions.add('/' + name);
+ completions.add(prefix + name);
}
}
--
1.8.1.2

View File

@ -0,0 +1,89 @@
From ebda44887d817a442cb4073d3ba3aaaf1fc22ae2 Mon Sep 17 00:00:00 2001
From: Phillip Schichtel <quick_wango@code-infection.de>
Date: Fri, 5 Jul 2013 21:55:00 +1000
Subject: [PATCH] Console Command Completion
changed exception handling
wrapped the tab completion in a waitable to sync it with the main thread
Implement command tab completion in the console. Adds BUKKIT-4168
Even though JLine provides an API for tab completion, there was still now tab
completion for console commands.
This commit implements tab completion in the console by providing the
ConsoleReader with a Completer implementation.
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index f33fdc1..2354ed2 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -16,6 +16,7 @@ import java.util.Map.Entry;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
+import org.bukkit.craftbukkit.command.ConsoleCommandCompleter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -54,6 +55,7 @@ public abstract class PlayerList {
public PlayerList(MinecraftServer minecraftserver) {
minecraftserver.server = new CraftServer(minecraftserver, this);
minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
+ minecraftserver.reader.addCompleter(new ConsoleCommandCompleter(minecraftserver.server));
this.cserver = minecraftserver.server;
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
new file mode 100644
index 0000000..b108bd1
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
@@ -0,0 +1,46 @@
+package org.bukkit.craftbukkit.command;
+
+import jline.console.completer.Completer;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.util.Waitable;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+
+public class ConsoleCommandCompleter implements Completer {
+ private final CraftServer server;
+
+ public ConsoleCommandCompleter(CraftServer server) {
+ this.server = server;
+ }
+
+ public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
+ Waitable<Integer> waitable = new Waitable<Integer>() {
+ @Override
+ protected Integer evaluate() {
+ List<String> offers = server.getCommandMap().tabComplete(server.getConsoleSender(), buffer);
+ if (offers == null) {
+ return cursor;
+ }
+ candidates.addAll(offers);
+
+ final int lastSpace = buffer.lastIndexOf(' ');
+ if (lastSpace == -1) {
+ return cursor - buffer.length();
+ } else {
+ return cursor - (buffer.length() - lastSpace - 1);
+ }
+ }
+ };
+ this.server.getServer().processQueue.add(waitable);
+ try {
+ return waitable.get();
+ } catch (ExecutionException e) {
+ this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return cursor;
+ }
+}
--
1.8.1.2