diff --git a/README.md b/README.md index 377e993..73ae736 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,8 @@ Sub-commands are supported. This is because all `Dispatcher`s are also `CommandCallable`s, so you can add a dispatcher to another dispatcher to another dispatcher! -In addition, Intake supports completion of arguments, although currently the -annotation method of command registration does not support the completion of -parameters in a command. You can complete sub-commands, however. +In addition, Intake supports completion of arguments through +`CommandCallable`s and `CommandCompleter`s The API supports a rich amount of metadata about each command, allowing the inspection of registered commands, their parameters, their permissions, and diff --git a/pom.xml b/pom.xml index b1c0a1f..ee83fff 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.sk89q intake - 3.1.1-SNAPSHOT + 3.1.2-SNAPSHOT jar diff --git a/src/main/java/com/sk89q/intake/Command.java b/src/main/java/com/sk89q/intake/Command.java index 69b031a..eac121a 100644 --- a/src/main/java/com/sk89q/intake/Command.java +++ b/src/main/java/com/sk89q/intake/Command.java @@ -99,4 +99,11 @@ */ boolean anyFlags() default false; + /** + * The command completer. + * + * @return the command completer, or {@link Class} if not set + */ + Class completer() default Class.class; + } diff --git a/src/main/java/com/sk89q/intake/parametric/ParametricBuilder.java b/src/main/java/com/sk89q/intake/parametric/ParametricBuilder.java index a830a5f..e43a090 100644 --- a/src/main/java/com/sk89q/intake/parametric/ParametricBuilder.java +++ b/src/main/java/com/sk89q/intake/parametric/ParametricBuilder.java @@ -64,6 +64,7 @@ public class ParametricBuilder { private final Map bindings = new HashMap(); private final List invokeListeners = new ArrayList(); private final List exceptionConverters = new ArrayList(); + private final Map completers = new HashMap(); private Authorizer authorizer = new NullAuthorizer(); private CommandCompleter defaultCompleter = new NullCompleter(); @@ -214,6 +215,15 @@ List getExceptionConverters() { return exceptionConverters; } + /** + * Get the map of custom completers. + * + * @return a map of custom completers. + */ + Map getCompleters() { + return completers; + } + /** * Get the authorizer. * @@ -254,4 +264,15 @@ public void setDefaultCompleter(CommandCompleter defaultCompleter) { this.defaultCompleter = defaultCompleter; } + /** + * Add a custom command suggestions provider that will be used if + * specified in a {@link Command} + * + * @param completer the custom command completer + */ + public void addCompleter(CommandCompleter completer) { + checkNotNull(completer); + completers.put(completer.getClass(), completer); + } + } diff --git a/src/main/java/com/sk89q/intake/parametric/ParametricCallable.java b/src/main/java/com/sk89q/intake/parametric/ParametricCallable.java index b3a41c3..33c6273 100644 --- a/src/main/java/com/sk89q/intake/parametric/ParametricCallable.java +++ b/src/main/java/com/sk89q/intake/parametric/ParametricCallable.java @@ -28,6 +28,7 @@ import com.sk89q.intake.Parameter; import com.sk89q.intake.Require; import com.sk89q.intake.SettableDescription; +import com.sk89q.intake.completion.CommandCompleter; import com.sk89q.intake.context.CommandContext; import com.sk89q.intake.context.CommandLocals; import com.sk89q.intake.parametric.annotation.Optional; @@ -65,6 +66,7 @@ class ParametricCallable implements CommandCallable { private final Set legacyFlags = new HashSet(); private final SettableDescription description = new SettableDescription(); private final Require permission; + private final CommandCompleter commandCompleter; /** * Create a new instance. @@ -182,6 +184,20 @@ class ParametricCallable implements CommandCallable { // Get permissions annotation permission = method.getAnnotation(Require.class); + + // Set command completer + if (definition.completer() == Class.class) { + // Set to default + commandCompleter = builder.getDefaultCompleter(); + } else { + // Set a custom completer + CommandCompleter customCompleter = builder.getCompleters().get(definition.completer()); + if (customCompleter == null) { + throw new ParametricException("Cannot find custom completer for " + definition.completer().getCanonicalName()); + } else { + commandCompleter = customCompleter; + } + } } @Override @@ -288,7 +304,7 @@ public boolean call(String stringArguments, CommandLocals locals, String[] paren @Override public List getSuggestions(String arguments, CommandLocals locals) throws CommandException { - return builder.getDefaultCompleter().getSuggestions(arguments, locals); + return commandCompleter.getSuggestions(arguments, locals); } /**