diff --git a/src/main/java/com/volmit/iris/util/decree/DecreeParameterHandler.java b/src/main/java/com/volmit/iris/util/decree/DecreeParameterHandler.java index 4b1091867..081c7b2bf 100644 --- a/src/main/java/com/volmit/iris/util/decree/DecreeParameterHandler.java +++ b/src/main/java/com/volmit/iris/util/decree/DecreeParameterHandler.java @@ -65,6 +65,12 @@ public interface DecreeParameterHandler { */ default KList getPossibilities(String input) { + if(input.trim().isEmpty()) + { + KList f = getPossibilities(); + return f == null ? new KList<>() : f; + } + input = input.trim(); KList possible = getPossibilities(); KList matches = new KList<>(); diff --git a/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java b/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java index 341ef6009..2a3611255 100644 --- a/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java +++ b/src/main/java/com/volmit/iris/util/decree/DecreeSystem.java @@ -47,9 +47,15 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { @Nullable @Override default List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - return new KList<>(); + Iris.debug("TAB COMPLETE ======================================================"); + KList enhanced = new KList<>(args); + KList v = getRoot().tabComplete(enhanced, enhanced.toString(" ")); + Iris.debug("input: '" + enhanced.toString(" ") + "'"); + v.removeDuplicates(); + return v; } + @Override default boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { J.aBukkit(() -> { @@ -62,6 +68,11 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { } static KList enhanceArgs(String[] args) + { + return enhanceArgs(args, true); + } + + static KList enhanceArgs(String[] args, boolean trim) { KList a = new KList<>(); @@ -73,15 +84,26 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { StringBuilder flat = new StringBuilder(); for(String i : args) { - if(i.trim().isEmpty()) + if(trim) { - continue; + if(i.trim().isEmpty()) + { + continue; + } + + flat.append(" ").append(i.trim()); } - flat.append(" ").append(i.trim()); + else + { + if(i.endsWith(" ")) + { + flat.append(" ").append(i.trim()).append(" "); + } + } } - flat = new StringBuilder(flat.substring(1).trim()); + flat = new StringBuilder(flat.length() > 0 ? trim ? flat.toString().trim().length() > 0 ?flat.substring(1).trim() : flat.toString().trim() : flat.substring(1) : flat); StringBuilder arg = new StringBuilder(); boolean quoting = false; @@ -93,7 +115,7 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { if(i == ' ' && !quoting) { - if(!arg.toString().trim().isEmpty()) + if(!arg.toString().trim().isEmpty() && trim) { a.add(arg.toString().trim()); arg = new StringBuilder(); @@ -113,7 +135,7 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { if(hasNext && j == ' ') { - if(!arg.toString().trim().isEmpty()) + if(!arg.toString().trim().isEmpty() && trim) { a.add(arg.toString().trim()); arg = new StringBuilder(); @@ -122,7 +144,7 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { else if(!hasNext) { - if(!arg.toString().trim().isEmpty()) + if(!arg.toString().trim().isEmpty() && trim) { a.add(arg.toString().trim()); arg = new StringBuilder(); @@ -137,7 +159,7 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter { } } - if(!arg.toString().trim().isEmpty()) + if(!arg.toString().trim().isEmpty() && trim) { a.add(arg.toString().trim()); } diff --git a/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java b/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java index 37b93c194..baff43692 100644 --- a/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java +++ b/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java @@ -171,6 +171,142 @@ public class VirtualDecreeCommand { return node != null; } + public KList tabComplete(KList args, String raw) + { + KList skip = new KList<>(); + KList tabs = new KList<>(); + invokeTabComplete(args, skip, tabs, raw); + return tabs; + } + + private boolean invokeTabComplete(KList args, KList skip, KList tabs, String raw) + { + if(isStudio() && !IrisSettings.get().isStudio()) + { + return false; + } + + if(isNode()) + { + tab(args, tabs); + skip.add(hashCode()); + return false; + } + + if(args.isEmpty()) + { + tab(args, tabs); + return true; + } + + String head = args.get(0); + + if (args.size() > 1 || head.endsWith(" ")) + { + VirtualDecreeCommand match = matchNode(head, skip); + + if(match != null) + { + args.pop(); + return match.invokeTabComplete(args, skip, tabs, raw); + } + + skip.add(hashCode()); + } + + else + { + tab(args, tabs); + } + + return false; + } + + private void tab(KList args, KList tabs) { + String last = null; + KList ignore = new KList<>(); + Runnable la = () -> { + + }; + for(String a : args) + { + la.run(); + last = a; + la = () -> { + if(isNode()) + { + String sea = a.contains("=") ? a.split("\\Q=\\E")[0] : a; + sea = sea.trim(); + + searching: for(DecreeParameter i : getNode().getParameters()) + { + for(String m : i.getNames()) + { + if(m.equalsIgnoreCase(sea) || m.toLowerCase().contains(sea.toLowerCase()) || sea.toLowerCase().contains(m.toLowerCase())) + { + ignore.add(i); + continue searching; + } + } + } + } + }; + } + + if(last != null) + { + if (isNode()) { + for(DecreeParameter i : getNode().getParameters()) + { + if(ignore.contains(i)) + { + Iris.info(i.getName() + " is ignored"); + continue; + } + + int g = 0; + + if(last.contains("=")) + { + String[] vv = last.trim().split("\\Q=\\E"); + String vx = vv.length == 2 ? vv[1] : ""; + for(String f : i.getHandler().getPossibilities(vx).convert((v) -> i.getHandler().toStringForce(v))) + { + g++; + tabs.add(i.getName() +"="+ f); + } + } + + else + { + for(String f : i.getHandler().getPossibilities("").convert((v) -> i.getHandler().toStringForce(v))) + { + g++; + tabs.add(i.getName() +"="+ f); + } + } + + if(g == 0) + { + tabs.add(i.getName() + "="); + } + } + } + + else + { + for(VirtualDecreeCommand i : getNodes()) + { + String m = i.getName(); + if(m.equalsIgnoreCase(last) || m.toLowerCase().contains(last.toLowerCase()) || last.toLowerCase().contains(m.toLowerCase())) + { + tabs.addAll(i.getNames()); + } + } + } + } + } + private KMap map(VolmitSender sender, KList in) { KMap data = new KMap<>(); @@ -396,8 +532,43 @@ public class VirtualDecreeCommand { return true; } + public KList matchAllNodes(String in) + { + KList g = new KList<>(); + + if(in.trim().isEmpty()) + { + g.addAll(nodes); + return g; + } + + for(VirtualDecreeCommand i : nodes) + { + if(i.matches(in)) + { + g.add(i); + } + } + + for(VirtualDecreeCommand i : nodes) + { + if(i.deepMatches(in)) + { + g.add(i); + } + } + + g.removeDuplicates(); + return g; + } + public VirtualDecreeCommand matchNode(String in, KList skip) { + if(in.trim().isEmpty()) + { + return null; + } + for(VirtualDecreeCommand i : nodes) { if(skip.contains(i.hashCode()))