From d484b99fc4eb0e5f38d883a704a625cce06eeaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Sun, 25 Oct 2020 05:51:39 +0100 Subject: [PATCH] :sparkles: Store the currently parsing argument in the command context This fixes #101 --- CHANGELOG.md | 1 + .../cloud/commandframework/CommandTree.java | 10 +++++++ .../context/CommandContext.java | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c69b0a2c..05a04695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added access to the CloudBrigadierManager from Brigadier-enabled command managers - Added parameter injectors + - Store currently parsing command argument in the command context ## [1.1.0] - 2020-10-24 diff --git a/cloud-core/src/main/java/cloud/commandframework/CommandTree.java b/cloud-core/src/main/java/cloud/commandframework/CommandTree.java index 41522384..e0b225a2 100644 --- a/cloud-core/src/main/java/cloud/commandframework/CommandTree.java +++ b/cloud-core/src/main/java/cloud/commandframework/CommandTree.java @@ -209,6 +209,7 @@ public final class CommandTree { final CommandContext.ArgumentTiming argumentTiming = commandContext.createTiming(argument); argumentTiming.setStart(System.nanoTime()); + commandContext.setCurrentArgument(argument); final ArgumentParseResult result = argument.getParser().parse(commandContext, commandQueue); argumentTiming.setEnd(System.nanoTime(), result.getFailure().isPresent()); @@ -377,6 +378,7 @@ public final class CommandTree { commandQueue ); if (!preParseResult.getFailure().isPresent() && preParseResult.getParsedValue().orElse(false)) { + commandContext.setCurrentArgument(argument); result = argument.getParser().parse(commandContext, commandQueue); } else { result = preParseResult; @@ -489,14 +491,17 @@ public final class CommandTree { if (commandQueue.isEmpty()) { return Collections.emptyList(); } else if (child.isLeaf() && commandQueue.size() < 2) { + commandContext.setCurrentArgument(child.getValue()); return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.peek()); } else if (child.isLeaf()) { if (child.getValue() instanceof CompoundArgument) { final String last = ((LinkedList) commandQueue).getLast(); + commandContext.setCurrentArgument(child.getValue()); return child.getValue().getSuggestionsProvider().apply(commandContext, last); } return Collections.emptyList(); } else if (commandQueue.peek().isEmpty()) { + commandContext.setCurrentArgument(child.getValue()); return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.remove()); } @@ -507,17 +512,20 @@ public final class CommandTree { ); if (preParseResult.getFailure().isPresent() || !preParseResult.getParsedValue().orElse(false)) { final String value = commandQueue.peek() == null ? "" : commandQueue.peek(); + commandContext.setCurrentArgument(child.getValue()); return child.getValue().getSuggestionsProvider().apply(commandContext, value); } // END: Preprocessing // START: Parsing + commandContext.setCurrentArgument(child.getValue()); final ArgumentParseResult result = child.getValue().getParser().parse(commandContext, commandQueue); if (result.getParsedValue().isPresent()) { commandContext.store(child.getValue().getName(), result.getParsedValue().get()); return this.getSuggestions(commandContext, commandQueue, child); } else if (result.getFailure().isPresent()) { final String value = commandQueue.peek() == null ? "" : commandQueue.peek(); + commandContext.setCurrentArgument(child.getValue()); return child.getValue().getSuggestionsProvider().apply(commandContext, value); } // END: Parsing @@ -532,6 +540,7 @@ public final class CommandTree { while (childIterator.hasNext()) { final Node> child = childIterator.next(); if (child.getValue() != null) { + commandContext.setCurrentArgument(child.getValue()); final ArgumentParseResult result = child.getValue().getParser().parse( commandContext, commandQueue @@ -555,6 +564,7 @@ public final class CommandTree { if (argument.getValue() == null || this.isPermitted(commandContext.getSender(), argument) != null) { continue; } + commandContext.setCurrentArgument(argument.getValue()); final List suggestionsToAdd = argument.getValue().getSuggestionsProvider() .apply(commandContext, stringOrEmpty(commandQueue.peek())); suggestions.addAll(suggestionsToAdd); diff --git a/cloud-core/src/main/java/cloud/commandframework/context/CommandContext.java b/cloud-core/src/main/java/cloud/commandframework/context/CommandContext.java index ed016108..e60da783 100644 --- a/cloud-core/src/main/java/cloud/commandframework/context/CommandContext.java +++ b/cloud-core/src/main/java/cloud/commandframework/context/CommandContext.java @@ -55,6 +55,8 @@ public final class CommandContext { private final boolean suggestions; private final CaptionRegistry captionRegistry; + private CommandArgument currentArgument = null; + /** * Create a new command context instance * @@ -285,6 +287,30 @@ public final class CommandContext { return this.flagContext; } + /** + * Get the argument that is currently being parsed for this command context. + * This value will be updated whenever the context is used to provide new + * suggestions or parse a new command argument + * + * @return Currently parsing {@link CommandArgument} or {@code null} + * @since 1.2.0 + */ + public @Nullable CommandArgument getCurrentArgument() { + return this.currentArgument; + } + + /** + * Set the argument that is currently being parsed for this command context. + * This value should be updated whenever the context is used to provide new + * suggestions or parse a new command argument + * + * @param argument Currently parsing {@link CommandArgument} or {@code null} + * @since 1.2.0 + */ + public void setCurrentArgument(final @Nullable CommandArgument argument) { + this.currentArgument = argument; + } + /** * Used to track performance metrics related to command parsing. This is attached