Add tab-completion API. Fixes BUKKIT-2181. Adds BUKKIT-2602
CommandMap contains a method that will auto-complete commands appropriately. Before the first space, it searches for commands of which the sender has permission. After the first space, it delegates to the individual command. Vanilla commands contain implementations to mimic vanilla implementation. Exception would be give, that allows for name matching; a feature we already allowed as part of the command is now supported for auto-complete as well. Plugin commands can get a tab completer set to delegate the completion for. If no tab completer is set, it can check the executor to see if it implements the tab completion interface. It will also attempt to chain calls if null gets returned from these interfaces. Plugins also implement the new TabCompleter interface, to add ease-of-use for plugin developers, similar to the onCommand() method. The default command implementation simply searches for player names. To help facilitate command completion, a utility class was added with two functions. One checks two strings, to see if the specified string starts with (ignoring case) the second. The other method uses the first to selectively copy elements from one collection to another. By: Score_Under <seejay.11@gmail.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@@ -8,6 +11,7 @@ import org.bukkit.plugin.Plugin;
|
||||
public final class PluginCommand extends Command implements PluginIdentifiableCommand {
|
||||
private final Plugin owningPlugin;
|
||||
private CommandExecutor executor;
|
||||
private TabCompleter completer;
|
||||
|
||||
protected PluginCommand(String name, Plugin owner) {
|
||||
super(name);
|
||||
@@ -69,6 +73,26 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
|
||||
return executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TabCompleter} to run when tab-completing this command.
|
||||
* If no TabCompleter is specified, and the command's executor implements
|
||||
* TabCompleter, then the executor will be used for tab completion.
|
||||
*
|
||||
* @param completer New tab completer
|
||||
*/
|
||||
public void setTabCompleter(TabCompleter completer) {
|
||||
this.completer = completer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link TabCompleter} associated with this command.
|
||||
*
|
||||
* @return TabCompleter object linked to this command
|
||||
*/
|
||||
public TabCompleter getTabCompleter() {
|
||||
return completer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owner of this PluginCommand
|
||||
*
|
||||
@@ -77,4 +101,47 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
|
||||
public Plugin getPlugin() {
|
||||
return owningPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}<br>
|
||||
* <br>
|
||||
* Delegates to the tab completer if present.<br>
|
||||
* If it is not present or returns null, will delegate to the current command
|
||||
* executor if it implements {@link TabCompleter}. If a non-null list has not
|
||||
* been found, will default to standard player name completion in
|
||||
* {@link Command#tabComplete(CommandSender, String, String[])}.<br>
|
||||
* <br>
|
||||
* This method does not consider permissions.
|
||||
* @throws CommandException if the completer or executor throw an exception during the process of tab-completing.
|
||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||
*/
|
||||
@Override
|
||||
public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException {
|
||||
Validate.notNull(sender, "Sender cannot be null");
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
List<String> completions = null;
|
||||
try {
|
||||
if (completer != null) {
|
||||
completions = completer.onTabComplete(sender, this, alias, args);
|
||||
}
|
||||
if (completions == null && executor instanceof TabCompleter) {
|
||||
completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Unhandled exception during tab completion for command '/").append(alias).append(' ');
|
||||
for (String arg : args) {
|
||||
message.append(arg).append(' ');
|
||||
}
|
||||
message.deleteCharAt(message.length() - 1).append("' in plugin ").append(owningPlugin.getDescription().getFullName());
|
||||
throw new CommandException(message.toString(), ex);
|
||||
}
|
||||
|
||||
if (completions == null) {
|
||||
return super.tabComplete(sender, alias, args);
|
||||
}
|
||||
return completions;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user