From 5f2fd93a5de2f44fd1bb05ebeaa1e3ea3df2db13 Mon Sep 17 00:00:00 2001
From: Luck <git@lucko.me>
Date: Sun, 5 Sep 2021 17:55:17 +0100
Subject: Fix tab completion on Fabric and Forge (#35)

---
 .../fabric/plugin/FabricClientSparkPlugin.java     |  7 +------
 .../fabric/plugin/FabricServerSparkPlugin.java     |  9 +--------
 .../spark/fabric/plugin/FabricSparkPlugin.java     | 22 ++++++++++++++++++++++
 3 files changed, 24 insertions(+), 14 deletions(-)

(limited to 'spark-fabric/src/main/java')

diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricClientSparkPlugin.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricClientSparkPlugin.java
index c7efb4e..0948225 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricClientSparkPlugin.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricClientSparkPlugin.java
@@ -118,12 +118,7 @@ public class FabricClientSparkPlugin extends FabricSparkPlugin implements Sugges
             return Suggestions.empty();
         }
 
-        return CompletableFuture.supplyAsync(() -> {
-            for (String suggestion : this.platform.tabCompleteCommand(new FabricCommandSender(this.minecraft.player, this), args)) {
-                builder.suggest(suggestion);
-            }
-            return builder.build();
-        });
+        return generateSuggestions(new FabricCommandSender(this.minecraft.player, this), args, builder);
     }
 
     private static String[] processArgs(String input, boolean tabComplete) {
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
index 19dbc8a..f0b6574 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricServerSparkPlugin.java
@@ -43,7 +43,6 @@ import net.minecraft.entity.player.PlayerEntity;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.command.CommandOutput;
 import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.server.network.ServerPlayerEntity;
 
 import java.util.Arrays;
 import java.util.concurrent.CompletableFuture;
@@ -94,13 +93,7 @@ public class FabricServerSparkPlugin extends FabricSparkPlugin implements Comman
             return Suggestions.empty();
         }
 
-        ServerPlayerEntity player = context.getSource().getPlayer();
-        return CompletableFuture.supplyAsync(() -> {
-            for (String suggestion : this.platform.tabCompleteCommand(new FabricCommandSender(player, this), args)) {
-                builder.suggest(suggestion);
-            }
-            return builder.build();
-        });
+        return generateSuggestions(new FabricCommandSender(context.getSource().getPlayer(), this), args, builder);
     }
 
     private static String[] processArgs(CommandContext<ServerCommandSource> context, boolean tabComplete) {
diff --git a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricSparkPlugin.java b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricSparkPlugin.java
index 50c6e44..a55d161 100644
--- a/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricSparkPlugin.java
+++ b/spark-fabric/src/main/java/me/lucko/spark/fabric/plugin/FabricSparkPlugin.java
@@ -26,10 +26,13 @@ import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.suggestion.SuggestionProvider;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 
 import me.lucko.spark.common.SparkPlatform;
 import me.lucko.spark.common.SparkPlugin;
+import me.lucko.spark.common.command.sender.CommandSender;
 import me.lucko.spark.common.sampler.ThreadDumper;
 import me.lucko.spark.common.util.ClassSourceLookup;
 import me.lucko.spark.fabric.FabricClassSourceLookup;
@@ -38,6 +41,7 @@ import me.lucko.spark.fabric.FabricSparkMod;
 import net.minecraft.server.command.CommandOutput;
 
 import java.nio.file.Path;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -95,6 +99,24 @@ public abstract class FabricSparkPlugin implements SparkPlugin {
         return new FabricClassSourceLookup();
     }
 
+    protected CompletableFuture<Suggestions> generateSuggestions(CommandSender sender, String[] args, SuggestionsBuilder builder) {
+        SuggestionsBuilder suggestions;
+
+        int lastSpaceIdx = builder.getRemaining().lastIndexOf(' ');
+        if (lastSpaceIdx != -1) {
+            suggestions = builder.createOffset(builder.getStart() + lastSpaceIdx + 1);
+        } else {
+            suggestions = builder;
+        }
+
+        return CompletableFuture.supplyAsync(() -> {
+            for (String suggestion : this.platform.tabCompleteCommand(sender, args)) {
+                suggestions.suggest(suggestion);
+            }
+            return suggestions.build();
+        });
+    }
+
     protected static <T> void registerCommands(CommandDispatcher<T> dispatcher, Command<T> executor, SuggestionProvider<T> suggestor, String... aliases) {
         if (aliases.length == 0) {
             return;
-- 
cgit