Skip to content

Commit 27cb30f

Browse files
feat: add @context annotation for CommandContext injection
Adds support for injecting the Brigadier CommandContext as a command parameter by annotating it with @context. This allows access to lower-level command execution details such as input parsing, argument nodes, and the command source. Example usage: ```java @executes void execute(CommandSender sender, @context CommandContext<?> ctx, int amount); ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 09de05f commit 27cb30f

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* StrokkCommands - A super simple annotation based zero-shade Paper command API library.
3+
* Copyright (C) 2025 Strokkur24
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
package net.strokkur.commands;
19+
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
/// Declares that a parameter should be injected with the Brigadier
26+
/// {@code CommandContext} instead of being interpreted as a command argument.
27+
///
28+
/// This annotation can be applied to any parameter of type {@code CommandContext<?>}
29+
/// in a method annotated with {@link Executes} or {@link DefaultExecutes}.
30+
///
31+
/// Example usage:
32+
/// ```java
33+
/// @Executes
34+
/// void execute(CommandSender sender, @Context CommandContext<?> ctx, int amount);
35+
/// ```
36+
///
37+
/// The annotated parameter will receive the raw Brigadier {@code CommandContext} at runtime,
38+
/// allowing access to lower-level command execution details such as input parsing,
39+
/// argument nodes, and the command source.
40+
@Retention(RetentionPolicy.SOURCE)
41+
@Target(ElementType.PARAMETER)
42+
public @interface Context {}

processor-common/src/main/java/net/strokkur/commands/internal/NodeUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package net.strokkur.commands.internal;
1919

20+
import net.strokkur.commands.Context;
2021
import net.strokkur.commands.Literal;
2122
import net.strokkur.commands.UnsetExecutorWrapper;
2223
import net.strokkur.commands.internal.abstraction.AnnotationsHolder;
@@ -26,6 +27,7 @@
2627
import net.strokkur.commands.internal.arguments.BrigadierArgumentConverter;
2728
import net.strokkur.commands.internal.arguments.BrigadierArgumentType;
2829
import net.strokkur.commands.internal.arguments.CommandArgument;
30+
import net.strokkur.commands.internal.arguments.ContextCommandArgument;
2931
import net.strokkur.commands.internal.arguments.LiteralCommandArgument;
3032
import net.strokkur.commands.internal.arguments.MultiLiteralCommandArgument;
3133
import net.strokkur.commands.internal.arguments.RequiredCommandArgument;
@@ -76,6 +78,13 @@ public List<CommandArgument> parseArguments(final List<? extends SourceVariable>
7678
for (final SourceVariable parameter : variables) {
7779
debug("| Parsing parameter: " + parameter.getName());
7880

81+
// Handle @Context annotation - inject CommandContext directly
82+
if (parameter.getAnnotation(Context.class) != null) {
83+
debug(" | Found @Context annotation, adding ContextCommandArgument");
84+
arguments.add(new ContextCommandArgument(parameter));
85+
continue;
86+
}
87+
7988
final Literal literal = parameter.getAnnotation(Literal.class);
8089
if (literal != null) {
8190
final String[] declared = literal.value();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* StrokkCommands - A super simple annotation based zero-shade Paper command API library.
3+
* Copyright (C) 2025 Strokkur24
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
package net.strokkur.commands.internal.arguments;
19+
20+
import net.strokkur.commands.internal.abstraction.SourceElement;
21+
22+
/// Represents a parameter annotated with {@code @Context} that should be injected
23+
/// with the Brigadier {@code CommandContext} at runtime.
24+
///
25+
/// Unlike other argument types, context arguments do not represent actual command
26+
/// arguments from the user input. Instead, they are injected directly from the
27+
/// execution context.
28+
public record ContextCommandArgument(SourceElement element) implements CommandArgument {
29+
30+
@Override
31+
public String argumentName() {
32+
return "ctx";
33+
}
34+
}

processor-common/src/main/java/net/strokkur/commands/internal/printer/TreePrinter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import net.strokkur.commands.internal.abstraction.SourceParameter;
2323
import net.strokkur.commands.internal.abstraction.SourceType;
2424
import net.strokkur.commands.internal.arguments.CommandArgument;
25+
import net.strokkur.commands.internal.arguments.ContextCommandArgument;
2526
import net.strokkur.commands.internal.arguments.LiteralCommandArgument;
2627
import net.strokkur.commands.internal.arguments.MultiLiteralCommandArgument;
2728
import net.strokkur.commands.internal.arguments.RequiredCommandArgument;
@@ -270,6 +271,7 @@ private void printArguments(final List<? extends CommandArgument> arguments) thr
270271
case RequiredCommandArgument req -> req.argumentType().retriever();
271272
case MultiLiteralCommandArgument ignored -> '"' + nextLiteral() + '"';
272273
case LiteralCommandArgument lit -> '"' + lit.literal() + '"';
274+
case ContextCommandArgument ignored -> "ctx";
273275
default -> throw new IllegalArgumentException("Unknown argument class: " + argument.getClass());
274276
});
275277

0 commit comments

Comments
 (0)