Skip to content

Commit

Permalink
autocomplete and alt. syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
vgskye committed Dec 9, 2024
1 parent 378b812 commit 574d3e1
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 6 deletions.
19 changes: 16 additions & 3 deletions common/src/main/java/vg/skye/EmojiMatcher.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package vg.skye;

import com.samsthenerd.inline.api.data.SpriteInlineData;
import com.samsthenerd.inline.api.matching.ContinuousMatcher;
import com.samsthenerd.inline.api.matching.MatchContext;
import com.samsthenerd.inline.api.matching.MatcherInfo;
import com.samsthenerd.inline.api.matching.*;
import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceLocation;

import java.util.regex.MatchResult;
Expand All @@ -12,8 +11,22 @@

public class EmojiMatcher implements ContinuousMatcher {
public static final EmojiMatcher INSTANCE = new EmojiMatcher();
public static final ContinuousMatcher STANDARD = new RegexMatcher.Standard(
"emoji",
"[a-z0-9_.-]+",
new ResourceLocation("emojiless", "emoji_standard"),
name -> {
var emoji = EmojilessClient.emojis.get(name);
if (emoji == null)
return null;
return new InlineMatch.DataMatch(new SpriteInlineData(emoji), Style.EMPTY);
},
MatcherInfo.fromId(new ResourceLocation("emojiless", "emoji_standard"))
);

private static final Pattern REGEX = Pattern.compile(":([a-z0-9_.-]+):");
public static final Pattern PARTIAL = Pattern.compile(":[a-z0-9_-]*$");
public static final Pattern PARTIAL_NEG = Pattern.compile(":[a-z0-9_.-]+:[a-z0-9_-]*$");

@Override
public ContinuousMatchResult match(String input, MatchContext matchContext) {
Expand Down
45 changes: 45 additions & 0 deletions common/src/main/java/vg/skye/EmojiSuggestion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package vg.skye;

import com.mojang.brigadier.context.StringRange;
import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions;

import java.util.ArrayList;
import java.util.List;

public class EmojiSuggestion extends Suggestion {
private final String value;
private EmojiSuggestion(StringRange range, String text) {
super(range, ":" + text + ": " + text);
this.value = text;
}

@Override
public String apply(String input) {
String valueToReplace = ":" + value + ":";
StringRange range = getRange();
if (range.getStart() == 0 && range.getEnd() == input.length()) {
return valueToReplace;
}
final StringBuilder result = new StringBuilder();
if (range.getStart() > 0) {
result.append(input, 0, range.getStart());
}
result.append(valueToReplace);
if (range.getEnd() < input.length()) {
result.append(input.substring(range.getEnd()));
}
return result.toString();
}

public static Suggestions suggest(String text, int start) {
List<Suggestion> result = new ArrayList<>();
String remaining = text.substring(start + 1);
for (String key: EmojilessClient.emojis.keySet()) {
if (key.startsWith(remaining)) {
result.add(new EmojiSuggestion(StringRange.between(start, text.length()), key));
}
}
return Suggestions.create(text, result);
}
}
1 change: 1 addition & 0 deletions common/src/main/java/vg/skye/EmojilessClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public final class EmojilessClient {

public static void init() {
InlineClientAPI.INSTANCE.addMatcher(EmojiMatcher.INSTANCE);
InlineClientAPI.INSTANCE.addMatcher(EmojiMatcher.STANDARD);
}

public static AnimatedTextureSprite readGif(ResourceLocation loc, ByteBuffer buf) throws IOException {
Expand Down
42 changes: 42 additions & 0 deletions common/src/main/java/vg/skye/mixin/CommandSuggestionsMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package vg.skye.mixin;

import com.mojang.brigadier.suggestion.Suggestions;
import com.samsthenerd.inline.api.client.InlineClientAPI;
import net.minecraft.client.gui.components.CommandSuggestions;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import vg.skye.EmojiMatcher;
import vg.skye.EmojiSuggestion;

import java.util.concurrent.CompletableFuture;

@Mixin(CommandSuggestions.class)
public abstract class CommandSuggestionsMixin {
@Shadow @Final
EditBox input;

@Shadow private CompletableFuture<Suggestions> pendingSuggestions;

@Shadow public abstract void showSuggestions(boolean bl);

@Inject(method = "updateCommandInfo", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/SharedSuggestionProvider;suggest(Ljava/lang/Iterable;Lcom/mojang/brigadier/suggestion/SuggestionsBuilder;)Ljava/util/concurrent/CompletableFuture;", shift = At.Shift.AFTER))
private void inject(CallbackInfo ci) {
if (!InlineClientAPI.INSTANCE.getConfig().isMatcherEnabled(new ResourceLocation("emojiless", "emoji")))
return;
String text = this.input.getValue();
int cursor = this.input.getCursorPosition();
String textUptoCursor = text.substring(0, cursor);
var negMatcher = EmojiMatcher.PARTIAL_NEG.matcher(textUptoCursor);
var matcher = EmojiMatcher.PARTIAL.matcher(textUptoCursor);
if (matcher.find() && !negMatcher.find()) {
this.pendingSuggestions = CompletableFuture.completedFuture(EmojiSuggestion.suggest(textUptoCursor, matcher.start()));
this.showSuggestions(false);
}
}
}
6 changes: 4 additions & 2 deletions common/src/main/resources/assets/emojiless/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"matcher.emojiless.emoji.title.styled": "Emojis",
"matcher.emojiless.emoji.description": "Displays shortcodes as emojis"
"matcher.emojiless.emoji.title.styled": "Emojis (shortcode syntax)",
"matcher.emojiless.emoji.description": "Displays shortcodes as emojis",
"matcher.emojiless.emoji_standard.title.styled": "Emojis (Inline syntax)",
"matcher.emojiless.emoji_standard.description": "Displays emojis using Inline syntax"
}
1 change: 1 addition & 0 deletions common/src/main/resources/emojiless.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"compatibilityLevel": "JAVA_17",
"minVersion": "0.8",
"client": [
"CommandSuggestionsMixin",
"NativeImageAccessor"
],
"mixins": [
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx2G
org.gradle.parallel=true

# Mod properties
mod_version = 1.1.0
mod_version = 1.2.0
maven_group = vg.skye
archives_name = emojiless
enabled_platforms = fabric,forge
Expand Down

0 comments on commit 574d3e1

Please sign in to comment.