From 78cc4ff51183b89e12aa39a47d39bf06497613ea Mon Sep 17 00:00:00 2001
From: DemonWav <demonwav@gmail.com>
Date: Mon, 29 Feb 2016 19:37:41 -0600
Subject: [PATCH] Add Location support to tab completers (vanilla feature
 missing in CraftBukkit)


diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
index 548d570..18c54b3 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -8,6 +8,7 @@ import java.util.Set;
 import org.apache.commons.lang.Validate;
 import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
+import org.bukkit.Location;
 import org.bukkit.Server;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.minecart.CommandMinecart;
@@ -109,6 +110,31 @@ public abstract class Command {
         return matchedPlayers;
     }
 
+    // Paper start - location tab-completes
+
+    /**
+     * Executed on tab completion for this command, returning a list of options the player can tab through. This method
+     * returns the {@link Location} of the block the player is looking at at the time of the tab complete.
+     * <p>
+     * Commands that want to use the Location information in their tab-complete implementations need to override this
+     * method. The Location provided by this method is the block that the player is currently looking at when the player
+     * attempts the tab complete. For this to be valid, the block must be highlighted by the player (i.e. the player is
+     * close enough to interact with the block).
+     *
+     * @param sender   Source object which is executing this command
+     * @param alias    the alias being used
+     * @param args     All arguments passed to the command, split via ' '
+     * @param location the location of the block the player is looking at
+     * @return a list of tab-completions for the specified arguments. This
+     * will never be null. List may be immutable.
+     * @throws IllegalArgumentException if sender, alias, or args is null
+     */
+    public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+        // Simply default to the standard tab-complete, subclasses can override this if needed
+        return tabComplete(sender, alias, args);
+    }
+    // Paper end
+
     /**
      * Returns the name of this command
      *
diff --git a/src/main/java/org/bukkit/command/PluginCommand.java b/src/main/java/org/bukkit/command/PluginCommand.java
index 3bfa31f..9b93872 100644
--- a/src/main/java/org/bukkit/command/PluginCommand.java
+++ b/src/main/java/org/bukkit/command/PluginCommand.java
@@ -3,6 +3,7 @@ package org.bukkit.command;
 import java.util.List;
 
 import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
 import org.bukkit.plugin.Plugin;
 
 /**
@@ -122,6 +123,15 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
      */
     @Override
     public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException {
+        return tabComplete(sender, alias, args, null); // Paper - The code from this method has been (slightly modified) moved to the Location method.
+    }
+
+    // PaperSpigot start - location tab-completes
+    /**
+     * This code was copied from tabComplete(CommandSender sender, String alias, String[] args)
+     */
+    @Override
+    public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws CommandException, IllegalArgumentException {
         Validate.notNull(sender, "Sender cannot be null");
         Validate.notNull(args, "Arguments cannot be null");
         Validate.notNull(alias, "Alias cannot be null");
@@ -129,10 +139,10 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
         List<String> completions = null;
         try {
             if (completer != null) {
-                completions = completer.onTabComplete(sender, this, alias, args);
+                completions = completer.onTabComplete(sender, this, alias, args, location); // Paper - add location argument
             }
             if (completions == null && executor instanceof TabCompleter) {
-                completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args);
+                completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args, location); // Paper - add location argument
             }
         } catch (Throwable ex) {
             StringBuilder message = new StringBuilder();
@@ -149,6 +159,7 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
         }
         return completions;
     }
+    // Paper end
 
     @Override
     public String toString() {
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
index a300ae7..980c4fd 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -12,6 +12,7 @@ import java.util.Map;
 import java.util.regex.Pattern;
 
 import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
 import org.bukkit.Server;
 import org.bukkit.command.defaults.*;
 import org.bukkit.entity.Player;
@@ -167,6 +168,14 @@ public class SimpleCommandMap implements CommandMap {
     }
 
     public List<String> tabComplete(CommandSender sender, String cmdLine) {
+        return tabComplete(sender, cmdLine, null); // Paper - location tab-completes, code moved below
+    }
+
+    // Paper start - location tab-completes
+    /**
+     * This code was copied, except for the noted change, from tabComplete(CommandSender sender, String cmdLine)
+     */
+    public List<String> tabComplete(CommandSender sender, String cmdLine, Location location) {
         Validate.notNull(sender, "Sender cannot be null");
         Validate.notNull(cmdLine, "Command line cannot null");
 
@@ -211,13 +220,14 @@ public class SimpleCommandMap implements CommandMap {
         String[] args = PATTERN_ON_SPACE.split(argLine, -1);
 
         try {
-            return target.tabComplete(sender, commandName, args);
+            return target.tabComplete(sender, commandName, args, location); // Paper - add location argument
         } catch (CommandException ex) {
             throw ex;
         } catch (Throwable ex) {
             throw new CommandException("Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target, ex);
         }
     }
+    // Paper end
 
     public Collection<Command> getCommands() {
         return Collections.unmodifiableCollection(knownCommands.values());
diff --git a/src/main/java/org/bukkit/command/TabCompleter.java b/src/main/java/org/bukkit/command/TabCompleter.java
index 6d61e3a..85b10e5 100644
--- a/src/main/java/org/bukkit/command/TabCompleter.java
+++ b/src/main/java/org/bukkit/command/TabCompleter.java
@@ -1,5 +1,7 @@
 package org.bukkit.command;
 
+import org.bukkit.Location;
+
 import java.util.List;
 
 /**
@@ -19,4 +21,10 @@ public interface TabCompleter {
      *     to default to the command executor
      */
     public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args);
+
+    // Paper start - location tab-completes
+    default List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args, Location location) {
+        return onTabComplete(sender, command, alias, args);
+    }
+    // Paper end
 }
-- 
2.7.2