Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a2fe2c0
feat: start work on named arguments in tags
Strokkur424 Sep 17, 2025
5314452
feat: modify token parser to parse named arguments
Strokkur424 Sep 18, 2025
0d783d7
chore: introduce new TokenType to uniquely distinguish value-less tog…
Strokkur424 Sep 18, 2025
22cb404
feat: (WIP) abstracting away TagProvider into QueuedTagProvider and N…
Strokkur424 Sep 18, 2025
a53e84b
fix: (WIP) parser should now theoretically be able to distinguish nam…
Strokkur424 Sep 19, 2025
3d7d3e9
feat: flesh out parsing logic further and fix a bunch of issues
Strokkur424 Sep 19, 2025
300e7fd
feat: add test for basic named argument parsing
Strokkur424 Sep 19, 2025
828f0b0
feat: start adding more tests
Strokkur424 Sep 19, 2025
b5d3c0b
fix: <red > tag with space being recognized as valid tag
Strokkur424 Sep 19, 2025
79647a0
feat: add a bunch more tests
Strokkur424 Sep 19, 2025
09265f7
chore: fix all compile time issues
Strokkur424 Sep 19, 2025
82e4e62
feat: add test
Strokkur424 Sep 19, 2025
a788770
chore: cleanup diff and rename to sequential
Strokkur424 Sep 19, 2025
a624524
chore: add a bunch more tests
Strokkur424 Sep 20, 2025
b412b8e
feat: add inverted flag arguments
Strokkur424 Sep 20, 2025
03e6342
feat: split the claiming resolvers into named and sequenced resolvers
Strokkur424 Sep 20, 2025
5901dee
feat: add missing context newException method and try to parse tag wi…
Strokkur424 Sep 20, 2025
bf049e4
feat: add isFlagPresent
Strokkur424 Sep 20, 2025
5ccbb63
fix: invalid tag in test
Strokkur424 Sep 20, 2025
951e763
feat: add named argument support to token emitter
Strokkur424 Sep 23, 2025
703ca92
feat: add flag support to token emitter
Strokkur424 Sep 23, 2025
2a1d129
chore: remove unused import
Strokkur424 Sep 23, 2025
9c7bc98
chore: default implement TagResolver methods with null
Strokkur424 Sep 23, 2025
49afd1f
chore: remove instanceof check in SequentialTagResolver in order to n…
Strokkur424 Sep 23, 2025
d2acca5
chore: add missing (at)since annotations
Strokkur424 Sep 23, 2025
4008b17
chore: spelling mistakes
Strokkur424 Sep 24, 2025
29b3561
Merge pull request #1 from Strokkur424/feat/named-arguments
Rossterd Oct 9, 2025
7815c87
Basic tag completions
Oct 10, 2025
683ce84
start on argument completions
Oct 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2025 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text.minimessage;

import java.util.Set;
import java.util.function.BiConsumer;
import org.jetbrains.annotations.NotNull;

/**
* Functional interface that creates autocompletions.
*
* @since 123.123.123
*/
@FunctionalInterface
public interface Completer {
/**
* Add completions to builder from context.
*
* @param completionContext the context
* @param builder the builder
* @since 123.123.123
*/
void complete(final @NotNull CompletionContext completionContext, final CompletionResult.@NotNull Builder builder);

/**
* Get a completer that doesn't add any completions.
*
* @return the completer.
* @since 123.123.123
*/
static Completer none() {
return (context, builder) -> {
};
}

/**
* Get a completer that completes only the tag key.
*
* @param key the key
* @return the completer
* @since 123.123.123
*/
static Completer noArgs(final String key) {
return (context, builder) -> {
if (context instanceof CompletionContext.TagKey) {
if (key.toLowerCase().startsWith(context.partial().toLowerCase())) {
builder.add(key);
}
}
};
}

/**
* Get a completer that completes only the tag keys.
*
* @param keys the keys
* @return the completer
* @since 123.123.123
*/
static Completer noArgs(final Set<String> keys) {
return (context, builder) -> {
if (context instanceof CompletionContext.TagKey) {
keys.stream()
.filter(key -> key.toLowerCase().startsWith(context.partial().toLowerCase()))
.forEach(builder::add);
}
};
}

/**
* Get a completer that completes tag keys, argument names and named argument values.
*
* @param tagKeys the tag keys
* @param argKeys the argument keys
* @param valueCompleter the named argument value completer
* @return the completer
* @since 123.123.123
*/
static Completer named(final Set<String> tagKeys, final Set<String> argKeys, final BiConsumer<CompletionContext.NamedArgumentValue, CompletionResult.Builder> valueCompleter) {
return (context, builder) -> {
if (context instanceof CompletionContext.TagKey) {
tagKeys.stream()
.filter(key -> key.toLowerCase().startsWith(context.partial().toLowerCase()))
.forEach(builder::add);
} else if (context instanceof CompletionContext.NamedArgumentKey) {
final CompletionContext.NamedArgumentKey keyContext = (CompletionContext.NamedArgumentKey) context;
if (tagKeys.contains(keyContext.tagKey().toLowerCase())) {
argKeys.stream()
.filter(key -> key.toLowerCase().startsWith(context.partial().toLowerCase()))
.filter(key -> keyContext.arguments().containsKey(key.toLowerCase()))
.forEach(builder::add);
}
} else if (context instanceof CompletionContext.NamedArgumentValue) {
final CompletionContext.NamedArgumentValue valueContext = (CompletionContext.NamedArgumentValue) context;
if (tagKeys.contains(valueContext.tagKey().toLowerCase())) {
valueCompleter.accept((CompletionContext.NamedArgumentValue) context, builder);
}
}
};
}

/**
* Get a completer that completes tag keys and sequential argument values.
*
* @param tagKeys the tag keys
* @param argumentValueCompleter the sequential argument values
* @return the completer
* @since 123.123.123
*/
static Completer sequential(final Set<String> tagKeys, final BiConsumer<CompletionContext.SequentialArgumentValue, CompletionResult.Builder> argumentValueCompleter) {
return (context, builder) -> {
if (context instanceof CompletionContext.TagKey) {
tagKeys.stream()
.filter(key -> key.toLowerCase().startsWith(context.partial().toLowerCase()))
.forEach(builder::add);
} else if (context instanceof CompletionContext.SequentialArgumentValue) {
final CompletionContext.SequentialArgumentValue valueContext = (CompletionContext.SequentialArgumentValue) context;
if (tagKeys.contains(valueContext.tagKey().toLowerCase())) {
argumentValueCompleter.accept(valueContext, builder);
}
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2025 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text.minimessage;

import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Context used to get Tag Completions.
*
* @since 123.123.123
*/
@ApiStatus.NonExtendable
public interface CompletionContext {
/**
* Get the unfinished partial value to complete.
*
* @return the partial value
* @since 123.123.123
*/
@NotNull String partial();

/**
* Completion context for a tag key.
*
* @since 123.123.123
*/
interface TagKey extends CompletionContext {
}

/**
* Completion context for the value of a sequential argument.
*
* @since 123.123.123
*/
interface SequentialArgumentValue extends CompletionContext {
/**
* Get the tag key.
*
* @return the tag key
* @since 123.123.123
*/
@NotNull String tagKey();

/**
* Get the arguments list.
*
* @return the list of arguments
* @since 123.123.123
*/
@NotNull List<String> arguments();
}

/**
* Completion context for a named argument key.
*
* @since 123.123.123
*/
interface NamedArgumentKey extends CompletionContext {
/**
* Get the tag key.
*
* @return the tag key
* @since 123.123.123
*/
@NotNull String tagKey();

/**
* Get the arguments list.
*
* @return the map of named arguments
* @since 123.123.123
*/
@NotNull Map<String, String> arguments();
}

/**
* Completion context for the value of a named argument.
*
* @since 123.123.123
*/
interface NamedArgumentValue extends CompletionContext {
/**
* Get the tag key.
*
* @return the tag key
* @since 123.123.123
*/
@NotNull String tagKey();

/**
* Get the arguments list.
*
* @return the map of named arguments
* @since 123.123.123
*/
@NotNull Map<String, String> arguments();

/**
* Get the key of the argument whose value is currently being parsed.
* Returns null in every state except NAMED_TAG_VALUE
*
* @return the argument key
*/
@Nullable String argKey();
}

/**
* Completion context generation when bad syntax is encountered.
*
* @since 123.123.123
*/
interface BadSyntax extends CompletionContext {
}
}
Loading
Loading