Despical / CommandFramework

A lightweight annotation based command system
https://spigotmc.org/resources/89933
GNU General Public License v3.0
23 stars 5 forks source link

[Feature] A more effective Auto Completer #11

Closed rokrieger closed 5 months ago

rokrieger commented 5 months ago

Description of the new feature

I don't know if it's already possible as I couldn't find any examples of this in the docs, but it would be nice if there was a way to create an enhanced autocomplete for subcommands.

There would be an autocomplete of the list for the player and an autocomplete for the list of kingdoms. Ex: /kingdom set

image

Because I'm having to do it this way:

    @Completer(name = "kingdom.set", aliases = {"k.set"}, permission = "kingdom.set")
    public List<String> setCompletions(CommandArguments args) {
        return Collections.singletonList("<player> <kingdom>");
    }

In this other example, I even manage to get the list of categories, but I can't get the list of players in the auto completer afterwards. image image

What I thought would be something like:

    @Completer(name = "shop.open.%category%", permission = "shop.open.others")
    public List<String> openPlayersCompletions(CommandArguments args) {
        return onlinePlayers.toList();
    }

My code:

    @Command(
            name = "shop",
            permission = "shop.open.categories",
            senderType = SenderType.PLAYER
    )
    public void openCategories(CommandArguments args) {
        new CategoriesMenu(args.getSender()).open();
    }

    @Command(
            name = "shop.open",
            permission = "shop.open.others",
            min = 2, max = 2,
            usage = "§cUsage: /shop open <category> <player>",
            desc = "Open specific category to specific player"
    )
    public void openCategoryForPlayer(ShopCategory category, CommandArguments args) {
        if (category == null) {
            return;
        }

        var player = Bukkit.getPlayer(Objects.requireNonNull(args.getArgument(1)));
        if (player == null) {
            args.sendMessage(ShopConfig.playerNotFoundMessage);
            return;
        }

        new ShopMenu(player, false, category).open();
    }

    @Completer(name = "shop", permission = "shop.open.others")
    public List<String> categoriesCompletions(CommandArguments args) {
        return Collections.singletonList("open <category> <player>");
    }

    @Completer(name = "shop.open", permission = "shop.open.others")
    public List<String> openCompletions(CommandArguments args) {
        return ShopManager.INSTANCE.getCategories().stream().map(ShopCategory::getId).toList();
    }
Despical commented 5 months ago

An example usage for the /shop command. Code is written in JDK 17.

@Completer(name = "shop", permission = "shop.open.others")
public List<String> categoriesCompletions() {
    return Collections.singletonList("open <category> <player>");
}

@Completer(name = "shop.open", permission = "shop.open.others")
public List<String> openCompletions(CommandArguments args) {
    if (args.getLength() == 1) {
        return ShopManager.INSTANCE.getCategories().stream().map(ShopCategory::getId).toList();
    }

    if (args.getLength() == 2) {
        return Bukkit.getOnlinePlayers().stream().map(Player::getName).toList();
    }

    return List.of();
}

You can do the same for /kingdom command. Let me know if that is what you want.

rokrieger commented 5 months ago

It worked fine! Thank you!