Giter VIP home page Giter VIP logo

adventure's People

Contributors

4drian3d avatar astei avatar bluelhf avatar bombardygamer avatar broccolai avatar camotoy avatar denwav avatar dependabot[bot] avatar draycia avatar electroid avatar emilyy-dev avatar joo200 avatar jpenilla avatar kashike avatar kennytv avatar kezz avatar kingofsquares avatar loohp avatar lucko avatar machine-maker avatar minidigger avatar moulberry avatar noahvdaa avatar powercasgamer avatar renovate-bot avatar renovate[bot] avatar rymiel avatar syldium avatar yusshu avatar zml2008 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adventure's Issues

Add font tag

Can you add a tag to set the font of a part of the text?

Add support for primitive data types

I should be able to append primitives like a string. See below

int claimBlocks = 50;
Component text = TextComponent.builder("").append(claimBlocks, TextColor.YELLOW).build();

Add suggestion of shading to readme

When you install multiple plugins, which use the Text library and multiple of them doesn't shade/relocate the lib itself, can the following warnings on Spigot appear:

[05:37:18] [Server thread/WARN]: [:plugin] Loaded class net.kyori.text.Component from :plugin which is not a depend, softdepend or loadbefore of this plugin.

I suggest adding a note, or code example to the readme, to inform about this step being recommended, if not even required.

Legacy serializer doesn't apply same color after linebreak

String str = "&cLine1\n&cLine2";
TextComponent comp = LegacyComponentSerializer.INSTANCE.deserialize(str, '&');
// comp looks fine - empty component, two children, "Line1\n" and "Line2", both red
// now serialize again:
str = LegacyComponentSerializer.INSTANCE.serialize(comp);
 // Not fine: "§cLine1\nLine2" - second red coloring dropped due to linked line thinking that text is still red. however, the client resets color when a newline is encountered, so "Line2" is white

https://github.com/KyoriPowered/text/blob/f83cd4cfc9fdb4ef41fff8188ceeaa5e4acd6a4d/serializer-legacy/src/main/java/net/kyori/text/serializer/legacy/AbstractLegacyComponentSerializer.java#L229

3+ colors/hexes in a gradient

Gradients right now doesn't allow 3+ colors/hexes but this feature can be pretty neat.

Image of 3+ gradients

The small bandage for now.

<gradient:#000000:#ffffff>||||||||||||||||||||||||</gradient><gradient:#ffffff:#000000>||||||||||||||||||||||||</gradient>
<gradient:red:blue>||||||||||||||||||||||||</gradient><gradient:blue:green>||||||||||||||||||||||||</gradient><gradient:green:yellow>||||||||||||||||||||||||</gradient><gradient:yellow:red>||||||||||||||||||||||||</gradient>

Semantic versioning needed

One of my libraries, SupaCommons, uses text, but due to the versioning my library breaks with text API changes since they are pushed to the same version, which is currently 1.12-SNAPSHOT.

Trailing colors not applied after TextComponent append

I've got a TextComponent defined as a prefix which is applied to all messages. At the end of the prefix, there is a color code to be applied. Prefix: &7[&bPrefix&7] &a

The messages are then loaded as TextComponent objects.

Once ready to send, I append the message TextComponent to the prefix TextComponent.

The expected behavior is that the entirety of the message, until another code is found, should be green since the prefix has a trailing &a color code; however, the message appears white until another color code is found.

Example: http://prntscr.com/nkpxhj

NoSuchMethodError when trying to send messages.

Hi, I'm trying to send a message , and i'm using both 'text' repository, and 'text-adapter-bukkit' repository in order to send components to a player.
However when this happens i get a NoSuchMethodError:
java.lang.NoSuchMethodError: 'java.lang.String net.kyori.text.util.NameMap.name(java.lang.Object)'

More info:
Gradle build file:
PasteBin - gradle.build
Creating TextComponent Java code:

protected static TextComponent buildKashikeComponent(List<String> strings, List<String> hoverString) {
        if (strings.isEmpty())
            return TextComponent.empty();
        TextComponent.Builder builder = TextComponent.builder();
        TextComponent message = LegacyComponentSerializer.INSTANCE.deserialize(String.join("\n", strings), '&');
        if (!hoverString.isEmpty())
            message.hoverEvent(HoverEvent.showText(LegacyComponentSerializer.INSTANCE.deserialize(String.join("\n", hoverString), '&')));
        builder.append(message);
        return builder.build();
    }

Sending the components to a Player inside my plugin:

public static void sendIfNotEmptyComponent(TextComponent component, Player player) {
        if (!component.isEmpty())
            TextAdapter.sendComponent(player, component);
    }

If you can help understand why this is happening I'd be very happy )=

TextComponent builder constructing empty components

TextComponent.Builder builder = TextComponent.builder();
TextComponent test = builder.build();
if (test == TextComponent.empty()) {
    System.out.println("TEST IS EMPTY!");
}

The code above generates empty TextComponentImpl objects
TextComponentImpl{content=, children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}

I would expect if nothing is appended to the builder, it would just return TextComponent.empty() and trigger the print out in test above.

Word wrapping

The ability to word-wrap a component to a specific width - would most likely require #59.

public interface WordWrapper {
  @NonNull List<Component> wordWrap(final @NonNull Component component, final int width);
}

Negative offset font usage not working

I'm using this with negative fonts translate offset and it's not working because it doesn't use the correct json for it.

It should return
Image of actual negative font

But it doesn't.
Image of MiniMessage

And here's a gif of it.
Image of negative fonts not working

In that gif above, the command I used was
/tellraw @a [{"text":"Ahoy"},{"translate":"offset.-40","with":[{"color":"red","text":"mates!"}]}]

The json provided by MiniMessage was
{"text":"","extra":[{"text":"Ahoy "},{"translate":"offset.-40"},{"text":"mates!","color":"red"}]}

As for new MiniMessageFont().handleOffset("Ahoy <offset:-40><red>mates!"), it's just a simple method that replaces <offset: with <lang:offset.

Legacy color code parsing

When more than one color code is specified consecutively, the one which appears first is used, rather than the last.

For example, &a&9foo is parsed to foo with color green as opposed to foo with color blue.

Test case:

@Test
public void testFromColor() {
  final TextComponent component = TextComponent.builder("")
    .append(TextComponent.of("foo").color(TextColor.BLUE))
    .build();

  assertEquals(component, ComponentSerializers.LEGACY.deserialize("&a&9foo", '&'));
}
java.lang.AssertionError: 
Expected :TextComponent{content=, children=[TextComponent{content=foo, children=[], color=blue, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}], color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}
Actual   :TextComponent{content=, children=[TextComponent{content=foo, children=[], color=green, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}], color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}

I've tried playing around with LegacyComponentSerializer to work out a fix. I assume this is happening because the string is being parsed in reverse, meaning the first color code in the string is being read after the color code later in the string - hence overriding the last.

TextComponent.joinWith

It would be nice if there was an additional static method on TextComponent, like Sponge's Text.joinWith:

  • static TextComponent joinWith(TextComponent separator, Iterable<TextComponent> components)
  • static TextComponent joinWith(TextComponent separator, TextComponent... components)

Add BossBar support

public interface BossBar {
 @NonNull Component name();
 float percent();
 @NonNull Color color();
 @NonNull Overlay overlay();
 @NonNull Set<Flag> flags();
}

Assistance with this library

I'm currently working on a library which would allow text to be translated into TextComponents, using this library.
But I'm currently stuck at a way to make this as efficient as possible, which is why I ask now for some assistance if possible.

My library would allow to have some text like Hello. Do you know [Google](hover:{text:["Click me!"]},click:{url:"https://google.com"})? which would look for any appearance of [text](text) and translate those into TextComponents with hover and/or click events set, before adding the remaining text and returning a TextComponent containing the whole text with the above-mentioned changes (So the text would mostly stay normal while the word "Google" would have hover and click actions)

My biggest struggle is not how to get the text to add actions to (I have a Pattern made for this that should work) but how to combine the normal text with the changed text to return as a TextComponent.
Any help is greatly appreciated and if needed can I provide additional information.

Formatting flags not allways being detected

Description:

Using the string §r§r§c§k||§e§lProfile§c§k|| the first §k isn't picked up properly causing the resulting TextComponent to look like the below image.

Example code:

String name = "§r§r§c§k||§e§lProfile§c§k||";
TextComponent component = LegacyComponentSerializer.legacy().deserialize(name);

Debug view:

2020-07-06_23-01-08

Provide a simple way to replace components deeply when using a ComponentRenderer

Currently I am using the following code to render out styling and text replacements based on translation keys: https://gist.github.com/octylFractal/cdd92710b05b50613d96d2fee35427f2

However, my main issue is that I have to manually do deep replacement, and this leaves me open to bugs like forgetting that a translatable component can have args and children. It would be nice if adventure allowed me to write a ComponentRenderer that made the call I make at the top of render in the above code: component = replaceSubcomponents(component, context);

In this way, it would automatically deeply render all relevant parts, and as replaceSubcomponents would become part of adventure code, it would be well tested + supported by the library, as well as more likely to include any future sub-component cases.

[Feature Request] Newline alias tag

A useful feature would be a tag that would allow new lines in text.
It would be used something like this:

<hover:show_text:"<red>test:TEST</red><br><green>TEST</green>">TEST

Single style merge method.

Right now it's very inconvenient to merge two Styles, because you have to call multiple methods, and it doesn't even cover the insertion.

private static Style mergeStyle(Style first, Style second) {
    first = first
        .mergeColor(second)
        .mergeDecorations(second)
        .mergeEvents(second);
    String insertion = second.insertion();
    return insertion != null ? first.insertion(insertion) : first;
  }

A single merge method simplifies this and also reduces object creation.

Better error handling

for example:
https://hasteb.in/pategewe.lua

"<dark_gray>»<gray> To download it from the internet, <click:open_url:<pack_url>><hover:show_text:\"<green>/!\\ install it from Options/ResourcePacks in your game\"><green><bold>CLICK HERE</bold></hover></click>"

BaseComponent[] components = Pack.WELCOME_MESSAGE.toMiniMessage("url", url);

So I didn't replace <pack_url> by < url>

Legacy serializer does not properly apply coloring to compound component

Here's the component in question:

        TextComponent velocityWebsite = TextComponent.builder()
                .content("Visit the ")
                .append(TextComponent.builder("Velocity website")
                        .color(TextColor.GREEN)
                        .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.velocitypowered.com"))
                        .build())
                .append(TextComponent.of(" or the ").resetStyle())
                .append(TextComponent.builder("Velocity GitHub")
                        .color(TextColor.GREEN)
                        .clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/astei/velocity"))
                        .build())
                .build();

This is how it looks in-game, which is correct:

image

ComponentSerializers.LEGACY turns this component into Visit the §aVelocity website§r or the Velocity GitHub, which is not consistent with the in-game display. It should be more like Visit the §aVelocity website§r or the §aVelocity GitHub.

Using text 1.12-1.6.2.

Builder shouldn't require content

I shouldn't be required to pass content to builder when it can easily default to an empty string. See below

TextComponent.Builder builder = TextComponent.builder().append("This is a test").color(TextColor.RED).build();

Handling of mismatched tags

If a user provides <green>hello</red>, what would the expected response be? right now the MiniMessage parser appears to ignore the trailing </red>. Would it make sense to throw a parse error?

Color is lost when the text in the TextComponent goes to a second line

When trying to color a full message wrapped in a TextComponent, if that message happens to be too long and happens to go to the second line in the chat, the color is lost. This does not happen with the legacy serializer, which is the current workaround.

For example, this code will break it:
TextComponent.builder("This message is an example of a bug with KyoriPowered/Text. It is too long, so it goes to a second line, and unfortunately it loses its color :/").color(TextColor.RED).build()

Related: PaperMC/Velocity#91

Proper documentation/getting started guide

Sorry to ask this through an issue, but I wonder if there is a proper site, wiki or similar to get started with this library as the Readme doesn't cover everything you might wanna know.
Like if you could create a hover text from a List and how that would be done when it is possible.

I want to use this library but the lack of explanation for (most commonly) made methods makes it a bit hard, to begin with. Especially when you just begin with those things like I do right now.

And another question I have is if there is a method to use, that would parse the raw JSON based on what server version the plugin is running on considering that there seem to be two separate types of JSON formats.

Sort of a String#replace for working with Components

I'm looking for a way to take a config value like %displayname%: %message% and replace %displayname% and %message% with components (and somehow probably also parse & color codes at the same time (ex. %displayname%&r: %message%))

Example: (simplified for demonstration purposes, in the real world the replaced components could have click & hover events and wouldn't just be a simple text component with just content)

Component comp = TextComponent.of("%displayname%: %message%")
    .replace("%displayname", TextComponent.of("Steve"))
    .replace("%message%", TextComponent.of("Hello World!"));

TextComponent.join() is functioning wrong?

I just got version 3.0.4 of text to try and use the TextComponent.join() function.
This method either has a bug or is functioning wrong in my eyes as when you only have 1 TextComponent it tries to join it with nothing as can be seen in the image.

javaw_lPmyXoU6I8

The code used for executing the command can be found here: https://gist.github.com/StealWonders/96027959ddc0120c7cfcd3c806a30ccd
The output of line 15 is " 1 ".

If you need any further information, feedback or testing from me feel free to ask.

**Suggestion** make formatByLegacyChar(Char char) public

I might have missed where it's possible but I was wondering if the
`AbstractLegacyComponentSerializer.formatByLegacyChar(Char char) method could be made public ?

Why? I would like to be able to store a List against a series of regex's to allow dynamic colourization by keyword. Historically we did this with ChatColor
so we would start with a config file
/badmin/b > c
we take the regex create a pattern /badmin/b and then take c and get the ChatColor that it corresponds to. we store them in a map and use it to dynamically format chat.

We can use the c to create a TextComponent that contains the textFormat but not ideal as when we later need to apply it to other text its cumbersome.

Pixel width

The ability to find the pixel-width of a single character, or the content of an entire component (and children).

public interface PixelWidthSource {
  int width(final @NonNull Component component);

  int width(final char character);
}

Argument Formatting

A limiting factor in recent years with the new JSON chat system is the ability to construct messages with arguments conveniently and safely.

In my own systems, I have implemented an XML parser that takes XML code and converts it to a JSON text object. E.g. <span style="9">foo</span> translates to {"text": "foo", color: "blue"}

I also added the ability to have parameters in messages to be given in runtime. So <span style="9">foo {0}</span>, with {0} being "bar", translates to {"text": "foo bar", color: "blue"}.

Now, I've reached a point where parameters need to be more complicated in the form of text components. So when given <span style="9">foo {0}</span>, with {0} being a Component, translates to {"text": "foo", color: "blue", extra: [ {"text": "bar", color: "yellow"} ] }.

I know this falls outside of the project's scope currently as there is no ability to string format messages. However, since it is a text library I thought it might be fitting for those who wish to implement I18n-like systems or just organised messages.

XmlParser: https://github.com/BlurEngine/Blur/blob/master/src/main/java/com/blurengine/blur/text/xml/XmlParser.kt

<reset> doesn't work

As the title says, <reset> doesn't work with the example taken from the Spigot resource page.
Image of example
Image of <reset>

Legacy serializer translates into the wrong order

input: Your link code is &l4000&r. PM the bot on Discord (&l3XP3R1M3N2L B0T&r) containing just this &lcode&r as the &bmessage&r to link your accounts. with character &

here are the outputs with different versions of the library (api & legacy serializer):

adventure 4.0.0-SNAPSHOT (wrong works properly)

TextComponentImpl{content="Your link code is ", children=[
  TextComponentImpl{content="4000", children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}, 
  TextComponentImpl{content=". PM the bot on Discord (", children=[
    TextComponentImpl{content="3XP3R1M3N2L B0T", children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}
  ], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}, 
  TextComponentImpl{content=") containing just this ", children=[
    TextComponentImpl{content="code", children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}
  ], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}, 
  TextComponentImpl{content=" as the ", children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}, 
  TextComponentImpl{content="message", children=[], style=Style{color=aqua, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}, 
  TextComponentImpl{content=" to link your accounts.", children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}
], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null, font=null}}

text 3.0.1-3.0.4 (also wrong)

TextComponentImpl{content=Your link code is , children=[
  TextComponentImpl{content=4000, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}},
  TextComponentImpl{content=. PM the bot on Discord (, children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=) containing just this , children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content= as the , children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=message, children=[], style=Style{color=aqua, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content= to link your accounts., children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=3XP3R1M3N2L B0T, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=code, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}
], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}

text 3.0.0 (correct)

TextComponentImpl{content=Your link code is , children=[
  TextComponentImpl{content=4000, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=. PM the bot on Discord (, children=[
    TextComponentImpl{content=3XP3R1M3N2L B0T, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}
  ], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=) containing just this , children=[
    TextComponentImpl{content=code, children=[], style=Style{color=null, obfuscated=null, bold=true, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}
  ], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content= as the , children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content=message, children=[], style=Style{color=aqua, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}, 
  TextComponentImpl{content= to link your accounts., children=[], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}
], style=Style{color=null, obfuscated=null, bold=null, strikethrough=null, underlined=null, italic=null, clickEvent=null, hoverEvent=null, insertion=null}}

NBT Paths

In the later Minecraft versions, vanilla adds NBT path, which is much similar to sponge's dataquery except that one NBT path can represent multiple targets at once with its filtering and multi-index selection (in list) ability.

Given text partially depends on NBT path (the nbt components) and that part of the NBT path (in the path filters) model is already interfaced out in kyoripowered nbt library, maybe the NBT path can be considered to have a library.

Downsample RGB colors for viewers who can't see them

With the latest Minecraft client, we can send texts in any RGB color, rather than the previous space of only 16.

Full color isn't supported by every viewer of our text -- commonly used console libraries convert to ANSI based on legacy color codes, and we target clients all the way back to MC 1.8.

When unsupported colors are passed to the legacy serializer, it fails locally with an exception.
When unsupported colors are sent to players, the color will be stripped entirely and players will see white text.

Users of the API could only avoid these issues by tracking the capabilities of every individual version they target, or by not using RGB at all.

I've added some API, currently on NamedTextColor, to find the nearest legacy color from any RGB color, but it is not yet used in any of the serializers. I'm also not entirely satisfied with the algorithm used -- it tends to favor the grays, as relatively "average" colors numerically.

How should the different serializers handle it?

Allow for replacing first occurrence or arbitrary number of occurrences in TextComponent

Currently the only way to replace text in TextComponents is via replace(...), however that method replaces all occurrences of the supplied pattern in the TextComponent.

I would like for a way to replace only the first occurrence.

Current use case is for parsing placeholders in user input, however the user can supply the placeholder multiple times, and replace will replace all of them.
A method to replaceFirst or replace(int occurrences, Pattern pattern, UnaryOperator<TextComponent.Builder> builder) would resolve this issue without having to manipulate the input and remove all duplicate placeholders.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.