aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/CommonPatternInfo.kt42
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt26
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternGui.kt36
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternImpl.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternKeyOwner.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternList.kt41
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternListImpl.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternManager.kt124
-rw-r--r--src/main/resources/assets/skyhanni/gui/regexes.xml6
10 files changed, 247 insertions, 91 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
index 7c33cd1b2..4c3b6defb 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt
@@ -65,7 +65,7 @@ object StringUtils {
/**
* From https://stackoverflow.com/questions/10711494/get-values-in-treemap-whose-string-keys-start-with-a-pattern
*/
- fun <T> subMapWithKeysThatAreSuffixes(prefix: String, map: NavigableMap<String?, T>): Map<String?, T>? {
+ fun <T> subMapOfStringsStartingWith(prefix: String, map: NavigableMap<String, T>): NavigableMap<String, T> {
if ("" == prefix) return map
val lastKey = nextLexicographicallyStringWithSameLength(prefix)
return map.subMap(prefix, true, lastKey, false)
@@ -130,6 +130,12 @@ object StringUtils {
return default
}
+ fun String.substringBeforeLastOrNull(needle: String): String? {
+ val index = this.lastIndexOf(needle)
+ if (index < 0) return null
+ return this.substring(0, index)
+ }
+
fun encodeBase64(input: String) = Base64.getEncoder().encodeToString(input.toByteArray())
fun decodeBase64(input: String) = Base64.getDecoder().decode(input).decodeToString()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/CommonPatternInfo.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/CommonPatternInfo.kt
new file mode 100644
index 000000000..ca5460a4f
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/CommonPatternInfo.kt
@@ -0,0 +1,42 @@
+package at.hannibal2.skyhanni.utils.repopatterns
+
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
+
+sealed class CommonPatternInfo<R, C> : ReadOnlyProperty<Any?, C> {
+ abstract val isLoadedRemotely: Boolean
+
+ abstract val wasOverridden: Boolean
+
+ abstract val defaultPattern: R
+
+ abstract val key: String
+
+ abstract val value: C
+
+ /**
+ * Whether the pattern has obtained a lock on a code location and a key.
+ * Once set, no other code locations can access this repo pattern (and therefore the key).
+ * @see RepoPatternManager.checkExclusivity
+ */
+ internal var hasObtainedLock = false
+
+
+ override fun getValue(thisRef: Any?, property: KProperty<*>): C {
+ verifyLock(thisRef, property)
+ return value
+ }
+
+ /**
+ * Try to lock the [key] to this key location.
+ * @see RepoPatternManager.checkExclusivity
+ */
+ private fun verifyLock(thisRef: Any?, property: KProperty<*>) {
+ if (hasObtainedLock) return
+ hasObtainedLock = true
+ val owner = RepoPatternKeyOwner(thisRef?.javaClass, property)
+ RepoPatternManager.checkExclusivity(owner, key)
+ }
+
+ abstract fun dump(): Map<String, String>
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt
index 6af2cf2fe..c0db43324 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPattern.kt
@@ -3,7 +3,6 @@ package at.hannibal2.skyhanni.utils.repopatterns
import at.hannibal2.skyhanni.SkyHanniMod
import org.intellij.lang.annotations.Language
import java.util.regex.Pattern
-import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
/**
@@ -41,43 +40,38 @@ import kotlin.reflect.KProperty
* When accessing the metaobject (the RepoPattern instance itself), then you afford yourself less protection at the cost
* of slightly more options.
*/
-interface RepoPattern : ReadOnlyProperty<Any?, Pattern> {
+sealed class RepoPattern : CommonPatternInfo<String, Pattern>() {
/**
* Check whether [value] has been loaded remotely or from the fallback value at [defaultPattern]. In case this is
* accessed off-thread there are no guarantees for the correctness of this value in relation to any specific call
* to [value].
*/
- val isLoadedRemotely: Boolean
+ abstract override val isLoadedRemotely: Boolean
/**
* Check whether [value] was compiled from a value other than the [defaultPattern]. This is `false` even when
* loading remotely if the remote pattern matches the local one.
*/
- val wasOverridden: Boolean
+ abstract override val wasOverridden: Boolean
/**
* The default pattern that is specified at compile time. This local pattern will be a fallback in case there is no
* remote pattern available or the remote pattern does not compile.
*/
- val defaultPattern: String
+ abstract override val defaultPattern: String
/**
- * Key for this pattern. Used as an identifier when loading from the repo. Should be consistent accross versions.
+ * Key for this pattern. Used as an identifier when loading from the repo. Should be consistent across versions.
*/
- val key: String
+ abstract override val key: String
/**
* Should not be accessed directly. Instead, use delegation at one code location and share the regex from there.
* ```kt
- * val actualValue by pattern
+ * val actualValue: Pattern by pattern
* ```
*/
- val value: Pattern
-
- override fun getValue(thisRef: Any?, property: KProperty<*>): Pattern {
- return value
- }
-
+ abstract override val value: Pattern
companion object {
/**
@@ -88,6 +82,10 @@ interface RepoPattern : ReadOnlyProperty<Any?, Pattern> {
return RepoPatternManager.of(key, fallback)
}
+ fun list(key: String, @Language("RegExp") vararg fallbacks: String): RepoPatternList {
+ return RepoPatternManager.ofList(key, fallbacks)
+ }
+
/**
* Obtains a [RepoPatternGroup] to allow for easier defining [RepoPattern]s with common prefixes.
*/
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternGui.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternGui.kt
index 2a2393686..9e3a36969 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternGui.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternGui.kt
@@ -7,6 +7,7 @@ import io.github.moulberry.moulconfig.gui.GuiScreenElementWrapperNew
import io.github.moulberry.moulconfig.observer.ObservableList
import io.github.moulberry.moulconfig.xml.Bind
import io.github.moulberry.moulconfig.xml.XMLUniverse
+import net.minecraft.client.Minecraft
/**
* Gui for analyzing [RepoPattern]s
@@ -29,30 +30,43 @@ class RepoPatternGui private constructor() {
@field:Bind
var search: String = ""
private var lastSearch = null as String?
- private val allKeys = RepoPatternManager.allPatterns.toList()
+ private val allKeys = RepoPatternManager.allPatterns
+ .toList()
.sortedBy { it.key }
.map { RepoPatternInfo(it) }
private var searchCache = ObservableList(mutableListOf<RepoPatternInfo>())
class RepoPatternInfo(
- repoPatternImpl: RepoPatternImpl
+ repoPatternImpl: CommonPatternInfo<*, *>
) {
@field:Bind
val key: String = repoPatternImpl.key
+ val remoteData = when (repoPatternImpl) {
+ is RepoPatternList -> repoPatternImpl.value.map { it.pattern() }
+ is RepoPattern -> listOf(repoPatternImpl.value.pattern())
+ }
+
@field:Bind
- val regex: String = repoPatternImpl.value.pattern()
+ val regex: String = remoteData.joinToString("\n")
@field:Bind
- val hoverRegex: List<String> = if (repoPatternImpl.isLoadedRemotely) {
- listOf(
- "§aLoaded remotely",
- "§7Remote: " + repoPatternImpl.compiledPattern.pattern(),
- "§7Local: " + repoPatternImpl.defaultPattern,
- )
- } else {
- listOf("§cLoaded locally", "§7Local: " + repoPatternImpl.defaultPattern)
+ val hoverRegex: List<String> = run {
+ val localPatterns = when (repoPatternImpl) {
+ is RepoPatternList -> repoPatternImpl.defaultPattern
+ is RepoPattern -> listOf(repoPatternImpl.defaultPattern)
+ }
+ if (repoPatternImpl.isLoadedRemotely) {
+ listOf(
+ "§aLoaded remotely",
+ "§7Remote:",
+ ) + remoteData.map { " §f- $it" } + listOf(
+ "§7Local:",
+ ) + localPatterns.map { " §f- $it" }
+ } else {
+ listOf("§cLoaded locally", "§7Local:") + localPatterns.map { " §f- $it" }
+ }
}
@field:Bind
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternImpl.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternImpl.kt
index 89e9f99ec..c2644f79b 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternImpl.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternImpl.kt
@@ -1,7 +1,6 @@
package at.hannibal2.skyhanni.utils.repopatterns
import java.util.regex.Pattern
-import kotlin.reflect.KProperty
/**
* Internal class implementing [RepoPattern]. Obtain via [RepoPattern.pattern].
@@ -9,41 +8,11 @@ import kotlin.reflect.KProperty
class RepoPatternImpl(
override val defaultPattern: String,
override val key: String,
-) : RepoPattern {
- var compiledPattern: Pattern = Pattern.compile(defaultPattern)
- var wasLoadedRemotely = false
+) : RepoPattern() {
override var wasOverridden = false
-
- /**
- * Whether the pattern has obtained a lock on a code location and a key.
- * Once set, no other code locations can access this repo pattern (and therefore the key).
- * @see RepoPatternManager.checkExclusivity
- */
- var hasObtainedLock = false
-
- override fun getValue(thisRef: Any?, property: KProperty<*>): Pattern {
- verifyLock(thisRef, property)
- return super.getValue(thisRef, property)
- }
-
- /**
- * Try to lock the [key] to this key location.
- * @see RepoPatternManager.checkExclusivity
- */
- fun verifyLock(thisRef: Any?, property: KProperty<*>) {
- if (hasObtainedLock) return
- hasObtainedLock = true
- val owner = RepoPatternKeyOwner(thisRef?.javaClass, property)
- RepoPatternManager.checkExclusivity(owner, key)
+ override var value: Pattern = Pattern.compile(defaultPattern)
+ override var isLoadedRemotely: Boolean = false
+ override fun dump(): Map<String, String> {
+ return mapOf(key to defaultPattern)
}
-
-
- override val value: Pattern
- get() {
- return compiledPattern
- }
- override val isLoadedRemotely: Boolean
- get() {
- return wasLoadedRemotely
- }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternKeyOwner.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternKeyOwner.kt
index ccd98ff1c..1847db49f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternKeyOwner.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternKeyOwner.kt
@@ -5,4 +5,5 @@ import kotlin.reflect.KProperty
data class RepoPatternKeyOwner(
val ownerClass: Class<*>?,
val property: KProperty<*>?,
+ val shared: Boolean = false,
)
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternList.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternList.kt
new file mode 100644
index 000000000..352592f7e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternList.kt
@@ -0,0 +1,41 @@
+package at.hannibal2.skyhanni.utils.repopatterns
+
+import java.util.regex.Pattern
+
+/**
+ * A list of [RepoPattern]s. It can be used almost identically, but will instead provide a [List] of [Pattern]s
+ */
+sealed class RepoPatternList : CommonPatternInfo<List<String>, List<Pattern>>() {
+ /**
+ * Check whether [value] has been loaded remotely or from the fallback value at [defaultPattern]. In case this is
+ * accessed off-thread there are no guarantees for the correctness of this value in relation to any specific call
+ * to [value].
+ */
+ abstract override val isLoadedRemotely: Boolean
+
+ /**
+ * Check whether [value] was compiled from a value other than the [defaultPattern]. This is `false` even when
+ * loading remotely if the remote pattern matches the local one.
+ */
+ abstract override val wasOverridden: Boolean
+
+ /**
+ * The default patterns that is specified at compile time. This local patterns will be a fallback in case there are
+ * no remote patterns available or the remote patterns do not compile.
+ */
+ abstract override val defaultPattern: List<String>
+
+ /**
+ * Key for this pattern list. When loading identifiers from the repo, this will pull all identifiers
+ * that start with the key, followed by `.{number}`. Should be consistent across versions.
+ */
+ abstract override val key: String
+
+ /**
+ * Should not be accessed directly. Instead, use delegation at one code location and share the regexes from there.
+ * ```kt
+ * val actualValue: List<Pattern> by pattern
+ * ```
+ */
+ abstract override val value: List<Pattern>
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternListImpl.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternListImpl.kt
new file mode 100644
index 000000000..e35b4e8e2
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternListImpl.kt
@@ -0,0 +1,13 @@
+package at.hannibal2.skyhanni.utils.repopatterns
+
+import java.util.regex.Pattern
+
+class RepoPatternListImpl(fallback: List<String>, override val key: String) : RepoPatternList() {
+ override var isLoadedRemotely: Boolean = false
+ override var wasOverridden: Boolean = false
+ override val defaultPattern: List<String> = fallback
+ override var value: List<Pattern> = fallback.map(Pattern::compile)
+ override fun dump(): Map<String, String> {
+ return defaultPattern.withIndex().associate { (key + "." + it.index) to it.value }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternManager.kt
index 5140aa186..6799f42d4 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/repopatterns/RepoPatternManager.kt
@@ -7,11 +7,15 @@ import at.hannibal2.skyhanni.events.LorenzEvent
import at.hannibal2.skyhanni.events.PreInitFinishedEvent
import at.hannibal2.skyhanni.events.RepositoryReloadEvent
import at.hannibal2.skyhanni.utils.LorenzUtils.afterChange
+import at.hannibal2.skyhanni.utils.StringUtils
import at.hannibal2.skyhanni.utils.StringUtils.matches
+import at.hannibal2.skyhanni.utils.StringUtils.substringBeforeLastOrNull
import net.minecraft.launchwrapper.Launch
import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.io.File
+import java.util.NavigableMap
+import java.util.TreeMap
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException
@@ -19,7 +23,7 @@ import java.util.regex.PatternSyntaxException
* Manages [RepoPattern]s.
*/
object RepoPatternManager {
- val allPatterns: Collection<RepoPatternImpl> get() = usedKeys.values
+ val allPatterns: Collection<CommonPatternInfo<*, *>> get() = usedKeys.values
/**
* Remote loading data that will be used to compile regexes from, once such a regex is needed.
@@ -35,7 +39,7 @@ object RepoPatternManager {
* Map containing all keys and their repo patterns. Used for filling in new regexes after an update, and for
* checking duplicate registrations.
*/
- private var usedKeys = mutableMapOf<String, RepoPatternImpl>()
+ private var usedKeys: NavigableMap<String, CommonPatternInfo<*, *>> = TreeMap()
private var wasPreinitialized = false
private val isInDevEnv = Launch.blackboard["fml.deobfuscatedEnvironment"] as Boolean
@@ -55,12 +59,24 @@ object RepoPatternManager {
*/
fun checkExclusivity(owner: RepoPatternKeyOwner, key: String) {
synchronized(exclusivity) {
- val previousOwner = exclusivity.get(key)
- if (previousOwner != owner && previousOwner != null) {
- if (!config.tolerateDuplicateUsage)
- crash("Non unique access to regex at \"$key\". First obtained by ${previousOwner.ownerClass} / ${previousOwner.property}, tried to use at ${owner.ownerClass} / ${owner.property}")
- } else {
- exclusivity[key] = owner
+ run {
+ val previousOwner = exclusivity[key]
+ if (previousOwner != owner && previousOwner != null) {
+ if (!config.tolerateDuplicateUsage)
+ crash("Non unique access to regex at \"$key\". First obtained by ${previousOwner.ownerClass} / ${previousOwner.property}, tried to use at ${owner.ownerClass} / ${owner.property}")
+ } else {
+ exclusivity[key] = owner
+ }
+ }
+ run {
+ val parent = key.substringBeforeLastOrNull(".") ?: return
+ val previousParentOwner = exclusivity[parent]
+ if (previousParentOwner != null && !previousParentOwner.shared) {
+ if (!config.tolerateDuplicateUsage)
+ crash("Non unique access to array regex at \"$parent\". First obtained by ${previousParentOwner.ownerClass} / ${previousParentOwner.property}, tried to use at ${owner.ownerClass} / ${owner.property}")
+ } else {
+ exclusivity[parent] = owner.copy(shared = true)
+ }
}
}
}
@@ -83,25 +99,65 @@ object RepoPatternManager {
*/
private fun reloadPatterns() {
val remotePatterns =
- if (config.forceLocal.get()) mapOf()
- else regexes?.regexes ?: mapOf()
-
+ TreeMap(
+ if (config.forceLocal.get()) mapOf()
+ else regexes?.regexes ?: mapOf()
+ )
for (it in usedKeys.values) {
- val remotePattern = remotePatterns[it.key]
- try {
- if (remotePattern != null) {
- it.compiledPattern = Pattern.compile(remotePattern)
- it.wasLoadedRemotely = true
- it.wasOverridden = remotePattern != it.defaultPattern
- continue
- }
- } catch (e: PatternSyntaxException) {
- SkyHanniMod.logger.error("Error while loading pattern from repo", e)
+ when (it) {
+ is RepoPatternListImpl -> loadArrayPatterns(remotePatterns, it)
+ is RepoPatternImpl -> loadStandalonePattern(remotePatterns, it)
+ }
+ }
+ }
+
+ private fun loadStandalonePattern(remotePatterns: TreeMap<String, String>, it: RepoPatternImpl) {
+ val remotePattern = remotePatterns[it.key]
+ try {
+ if (remotePattern != null) {
+ it.value = Pattern.compile(remotePattern)
+ it.isLoadedRemotely = true
+ it.wasOverridden = remotePattern != it.defaultPattern
+ return
}
- it.compiledPattern = Pattern.compile(it.defaultPattern)
- it.wasLoadedRemotely = false
- it.wasOverridden = false
+ } catch (e: PatternSyntaxException) {
+ SkyHanniMod.logger.error("Error while loading pattern from repo", e)
}
+ it.value = Pattern.compile(it.defaultPattern)
+ it.isLoadedRemotely = false
+ it.wasOverridden = false
+ }
+
+ private fun loadArrayPatterns(remotePatterns: TreeMap<String, String>, arrayPattern: RepoPatternListImpl) {
+ val prefix = arrayPattern.key + "."
+ val remotePatternList = StringUtils.subMapOfStringsStartingWith(prefix, remotePatterns)
+ val patternMap = remotePatternList.mapNotNull {
+ val index = it.key.removePrefix(prefix).toIntOrNull()
+ if (index == null) null
+ else index to it.value
+ }
+
+ fun setDefaultPatterns() {
+ arrayPattern.value = arrayPattern.defaultPattern.map(Pattern::compile)
+ arrayPattern.isLoadedRemotely = false
+ arrayPattern.wasOverridden = false
+ }
+
+ if (patternMap.mapTo(mutableSetOf()) { it.first } != patternMap.indices.toSet()) {
+ SkyHanniMod.logger.error("Incorrect index set for $arrayPattern")
+ setDefaultPatterns()
+ }
+
+ val patternStrings = patternMap.sortedBy { it.first }.map { it.second }
+ try {
+ arrayPattern.value = patternStrings.map(Pattern::compile)
+ arrayPattern.isLoadedRemotely = true
+ arrayPattern.wasOverridden = patternStrings != arrayPattern.defaultPattern
+ return
+ } catch (e: PatternSyntaxException) {
+ SkyHanniMod.logger.error("Error while loading pattern from repo", e)
+ }
+ setDefaultPatterns()
}
val keyShape = Pattern.compile("^(?:[a-z0-9A-Z]+\\.)*[a-z0-9A-Z]+$")
@@ -121,7 +177,8 @@ object RepoPatternManager {
ConfigManager.gson.toJson(
RepoPatternDump(
sourceLabel,
- usedKeys.values.associate { it.key to it.defaultPattern })
+ usedKeys.values.flatMap { it.dump().toList() }.toMap()
+ )
)
file.parentFile.mkdirs()
file.writeText(data)
@@ -146,9 +203,24 @@ object RepoPatternManager {
crash("Illegal late initialization of repo pattern. Repo pattern needs to be created during pre-initialization.")
}
if (key in usedKeys) {
- exclusivity[key] = RepoPatternKeyOwner(null, null)
usedKeys[key]?.hasObtainedLock = false
}
return RepoPatternImpl(fallback, key).also { usedKeys[key] = it }
}
+
+ fun ofList(key: String, fallbacks: Array<out String>): RepoPatternList {
+ verifyKeyShape(key)
+ if (wasPreinitialized && !config.tolerateLateRegistration) {
+ crash("Illegal late initialization of repo pattern. Repo pattern needs to be created during pre-initialization.")
+ }
+ if (key in usedKeys) {
+ usedKeys[key]?.hasObtainedLock = false
+ }
+ StringUtils.subMapOfStringsStartingWith(key, usedKeys).forEach {
+ it.value.hasObtainedLock = false
+ }
+ return RepoPatternListImpl(fallbacks.toList(), key).also { usedKeys[key] = it }
+
+ }
+
}
diff --git a/src/main/resources/assets/skyhanni/gui/regexes.xml b/src/main/resources/assets/skyhanni/gui/regexes.xml
index 7ba1feaef..d9b20d171 100644
--- a/src/main/resources/assets/skyhanni/gui/regexes.xml
+++ b/src/main/resources/assets/skyhanni/gui/regexes.xml
@@ -7,14 +7,14 @@
<TextField value="@search"/>
<Text text="@poll"/>
</Row>
- <ScrollPanel width="360" height="266">
+ <ScrollPanel width="560" height="400">
<Array data="@searchResults">
<Row>
<Hover lines="@keyW">
- <Text text="@key" width="100"/>
+ <Text text="@key" width="200"/>
</Hover>
<Hover lines="@hoverRegex">
- <Text text="@regex" width="200"/>
+ <Text text="@regex" width="300"/>
</Hover>
<Text text="@overriden" width="50"/>
</Row>