diff --git a/.idea/misc.xml b/.idea/misc.xml
index 03872dd..ecb0c83 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 1eb1391..af37b85 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,29 +4,30 @@
-
-
-
-
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -78,6 +79,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -134,41 +149,42 @@
- {
- "keyToString": {
- "Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [:kencommandapi-core:de.kentoj.kencommandapi.Main.main()].executor": "Run",
- "Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [build].executor": "Run",
- "Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [publish].executor": "Run",
- "Gradle.CommandParserTest.checkArgumentExpected.executor": "Run",
- "Gradle.Download Sources.executor": "Run",
- "Gradle.KenCommandAPI [:de.kencommand.Main.main()].executor": "Run",
- "Gradle.KenCommandAPI [assemble].executor": "Run",
- "Gradle.KenCommandAPI [buildEnvironment].executor": "Run",
- "Gradle.KenCommandAPI [build].executor": "Run",
- "Gradle.KenCommandAPI [clean test].executor": "Run",
- "Gradle.KenCommandAPI [clean].executor": "Run",
- "Gradle.KenCommandAPI [publishAllPublicationsToScrowRepository].executor": "Run",
- "Gradle.KenCommandAPI [publish].executor": "Run",
- "Gradle.KenCommandAPI [test].executor": "Run",
- "Gradle.KenCommandAPI:kencommandapi-bukkit [build].executor": "Run",
- "Gradle.KenCommandAPI:kencommandapi-bukkit [generatePomFileForKenCommandAPIBukkitPublication].executor": "Run",
- "Gradle.KenCommandAPI:kencommandapi-bukkit [publishAllPublicationsToScrowRepository].executor": "Run",
- "Gradle.KenCommandAPI:kencommandapi-bukkit [publish].executor": "Run",
- "Gradle.KenCommandAPI:kencommandapi-velocity [publish].executor": "Run",
- "Gradle.kencommandapi-core [build].executor": "Run",
- "ModuleVcsDetector.initialDetectionPerformed": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
- "RunOnceActivity.git.unshallow": "true",
- "git-widget-placeholder": "master",
- "kotlin-language-version-configured": "true",
- "last_opened_file_path": "/home/a/src/scrow/core",
- "project.structure.last.edited": "Modules",
- "project.structure.proportion": "0.15",
- "project.structure.side.proportion": "0.6268199",
- "settings.editor.selected.configurable": "preferences.pluginManager"
+
+}]]>
@@ -178,6 +194,7 @@
+
@@ -202,31 +219,7 @@
-
-
-
-
-
-
-
-
-
-
-
- false
- true
- false
- true
-
-
+
@@ -249,19 +242,40 @@
false
-
+
-
+
-
-
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -318,11 +332,11 @@
-
+
-
-
+
+
@@ -579,10 +593,11 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/TODO b/TODO
index f3e61d5..bfd9608 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,10 @@
+- version catalog
- suggest next literal/argument
- fix:
```
[22:05:39 ERROR]: Could not pass event AsyncTabCompleteEvent to CoreBukkit v1.0.0-SNAPSHOT
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
- at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.api.parser2.SuggestionCommandParser.getSuggestions(SuggestionCommandParser.java:39) ~[?:?]
+ at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.api.parser.SuggestionCommandParser.getSuggestions(SuggestionCommandParser.java:39) ~[?:?]
at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.api.CommandHandler.getSuggestions(CommandHandler.java:44) ~[?:?]
at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.TabCompleteListener.onAsyncTabComplete(TabCompleteListener.java:27) ~[?:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.11-R0.1-SNAPSHOT.jar:?]
diff --git a/kencommandapi-bukkit/build.gradle.kts b/kencommandapi-bukkit/build.gradle.kts
index 8a44f16..6c3efb3 100644
--- a/kencommandapi-bukkit/build.gradle.kts
+++ b/kencommandapi-bukkit/build.gradle.kts
@@ -5,14 +5,8 @@ plugins {
id("scrow.java-library")
}
-repositories {
- maven("https://repo.papermc.io/repository/maven-public/") {
- name = "papermc"
- }
-}
-
dependencies {
- compileOnly(project(":kencommandapi-core"))
+ api(project(":kencommandapi-core"))
compileOnly("io.papermc.paper:paper-api:1.21.11-rc3-R0.1-SNAPSHOT")
}
diff --git a/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java b/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java
index 70c0479..5a1179d 100644
--- a/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java
+++ b/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java
@@ -18,12 +18,19 @@ public class TabCompleteListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onAsyncTabComplete(AsyncTabCompleteEvent ev) {
if (!ev.isCommand()) return;
-
var args = ev.getBuffer().substring(1).split(" ");
+ if (args.length == 0) return;
+
var label = args[0];
+ {
+ // commands can be called with a ':' prefix. strip it.
+ int l = label.indexOf(':');
+ if (l >= 0)
+ label = label.substring(l+1);
+ }
var rootNode = commandAPI.getRegistered(label);
if (rootNode == null) return;
ev.setHandled(true);
- ev.setCompletions(commandHandler.getSuggestions(rootNode, ev.getSender(), Arrays.copyOfRange(args, 1, args.length)));
+ ev.setCompletions(commandHandler.getSuggestions(rootNode, ev.getSender(), Arrays.copyOfRange(args, 1, args.length), ev.getBuffer().endsWith(" ")));
}
}
diff --git a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java
index 9738558..c652460 100644
--- a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java
+++ b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java
@@ -2,12 +2,14 @@ package de.kentoj.kencommandapi.api;
import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.literal.RootLiteral;
-import de.kentoj.kencommandapi.api.parser2.InvocationCommandParser;
-import de.kentoj.kencommandapi.api.parser2.SuggestionCommandParser;
+import de.kentoj.kencommandapi.api.parser.CommandParseHelper;
+import de.kentoj.kencommandapi.api.parser.InvocationCommandParser;
+import de.kentoj.kencommandapi.api.parser.SuggestionCommandParser;
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
import de.kentoj.kencommandapi.api.platform.SendMessageMethod;
import lombok.RequiredArgsConstructor;
+import java.util.Arrays;
import java.util.List;
@RequiredArgsConstructor
@@ -20,13 +22,14 @@ public class CommandHandler {
public CommandHandler(SendMessageMethod sendMessageMethod, HasPermissionMethod hasPermissionMethod) {
this.sendMessageMethod = sendMessageMethod;
- invocationParser = new InvocationCommandParser<>(hasPermissionMethod);
- suggestionParser = new SuggestionCommandParser<>(hasPermissionMethod);
+ var parseHelper = new CommandParseHelper<>(hasPermissionMethod);
+ invocationParser = new InvocationCommandParser<>(parseHelper);
+ suggestionParser = new SuggestionCommandParser<>(parseHelper);
}
@SuppressWarnings("CodeBlock2Expr")
public void invoke(RootLiteral rootLiteral, T sender, String[] args) {
- invocationParser.invoke(rootLiteral, sender, args)
+ invocationParser.parse(rootLiteral, sender, Arrays.stream(args).iterator())
.ifSuccessOrElse(data -> {
var ctx = new CommandContext<>(sender, data.getArguments());
data.getExecutor().execute(ctx).whenComplete((result, ex) -> {
@@ -40,7 +43,8 @@ public class CommandHandler {
});
}
- public List getSuggestions(RootLiteral rootNode, T sender, String[] args) {
- return suggestionParser.getSuggestions(rootNode, sender, args);
+ public List getSuggestions(RootLiteral rootNode, T sender, String[] args, boolean trailingSpace) {
+ System.out.println("youre using the latest n greatest command parsing 3");
+ return suggestionParser.suggest(rootNode, sender, Arrays.stream(args).iterator(), trailingSpace);
}
}
\ No newline at end of file
diff --git a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/Literal.java b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/Literal.java
index 531905b..b017837 100644
--- a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/Literal.java
+++ b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/Literal.java
@@ -33,7 +33,6 @@ public interface Literal {
/**
* @throws IllegalArgumentException if there is already an argument with the same id
* @throws IllegalStateException if a greedy argument was added to the literal previously
- * @throws IllegalStateException if the literal already has a child literal assigned to it
*/
void addArgument(CommandArgument argument);
@@ -50,7 +49,6 @@ public interface Literal {
/**
* @throws IllegalArgumentException if there is already a literal with the same name
* @throws IllegalStateException if a greedy argument was added to the literal previously
- * @throws IllegalStateException if the literal already has an argument assigned to it
*/
void addLiteral(@NotNull Literal literal);
diff --git a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/CommandParseHelper.java b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/CommandParseHelper.java
new file mode 100644
index 0000000..94c13c2
--- /dev/null
+++ b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/CommandParseHelper.java
@@ -0,0 +1,26 @@
+package de.kentoj.kencommandapi.api.parser;
+
+import de.kentoj.kencommandapi.api.literal.Literal;
+import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Iterator;
+
+@RequiredArgsConstructor
+public final class CommandParseHelper {
+ private final HasPermissionMethod hasPermission;
+
+ public boolean hasPermission(T sender, Literal literal) {
+ if (literal.getPermission() == null) return true;
+ return hasPermission.test(sender, literal.getPermission());
+ }
+
+ public String parseInput(Iterator tokenIter, boolean isGreedy) {
+ if (!isGreedy)
+ return tokenIter.next();
+ var builder = new StringBuilder();
+ tokenIter.forEachRemaining(tok -> builder.append(" ").append(tok));
+ builder.deleteCharAt(0);
+ return builder.toString();
+ }
+}
\ No newline at end of file
diff --git a/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/InvocationCommandParser.java b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/InvocationCommandParser.java
new file mode 100644
index 0000000..25697ba
--- /dev/null
+++ b/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/InvocationCommandParser.java
@@ -0,0 +1,91 @@
+package de.kentoj.kencommandapi.api.parser;
+
+import com.leakyabstractions.result.api.Result;
+import com.leakyabstractions.result.core.Results;
+import de.kentoj.kencommandapi.api.argument.CommandArgument;
+import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
+import de.kentoj.kencommandapi.api.invocation.ParsedArgument;
+import de.kentoj.kencommandapi.api.literal.Literal;
+import de.kentoj.kencommandapi.api.literal.RootLiteral;
+import de.kentoj.kencommandapi.internal.ParsedArgumentImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.Value;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+@RequiredArgsConstructor
+public class InvocationCommandParser {
+ private final CommandParseHelper helper;
+
+ public Result parse(
+ RootLiteral rootLiteral,
+ T sender,
+ Iterator tokenIter
+ ) {
+ Literal currentLiteral = rootLiteral;
+ Map> parsedArguments = new HashMap<>();
+
+ while (true) {
+ {
+ var result = processArguments(currentLiteral, sender, tokenIter)
+ .ifSuccess(parsedArguments::putAll);
+ if (result.hasFailure())
+ return result.mapSuccess(__ -> null);
+ }
+
+ if (!tokenIter.hasNext()) {
+ if (currentLiteral.getExecutor() == null)
+ return Results.failure("Literal expected");
+ break;
+ }
+
+ var literalName = tokenIter.next();
+ var nextLiteral = currentLiteral.getLiteral(literalName);
+ var isIncompleteOrUnknown = nextLiteral == null || !helper.hasPermission(sender, nextLiteral);
+ if (isIncompleteOrUnknown)
+ return Results.failure("Unknown literal: " + literalName);
+ currentLiteral = nextLiteral;
+ }
+
+ return Results.success(new ExecutionData(currentLiteral.getExecutor(), parsedArguments));
+ }
+
+ private Result