aboutsummaryrefslogtreecommitdiffstats
path: root/config/quickshell/modules/common/functions/levendist.js
diff options
context:
space:
mode:
authorKiran George <kirangeorge1995@gmail.com>2025-06-09 11:30:08 +0530
committerKiran George <kirangeorge1995@gmail.com>2025-06-09 11:30:08 +0530
commit952aa63147c9fb28f6ace6f0bc7ccf45ced1299a (patch)
tree306e6d86603a162c00bc5113b56baac0fe7bec7c /config/quickshell/modules/common/functions/levendist.js
parent4cf0d0bd5930da76e60f6770de3ee97c10ca7024 (diff)
Overview v2
Diffstat (limited to 'config/quickshell/modules/common/functions/levendist.js')
-rw-r--r--config/quickshell/modules/common/functions/levendist.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/config/quickshell/modules/common/functions/levendist.js b/config/quickshell/modules/common/functions/levendist.js
new file mode 100644
index 00000000..90180d21
--- /dev/null
+++ b/config/quickshell/modules/common/functions/levendist.js
@@ -0,0 +1,141 @@
+// Original code from https://github.com/koeqaife/hyprland-material-you
+// Original code license: GPLv3
+// Translated to Js from Cython with an LLM and reviewed
+
+function min3(a, b, c) {
+ return a < b && a < c ? a : b < c ? b : c;
+}
+
+function max3(a, b, c) {
+ return a > b && a > c ? a : b > c ? b : c;
+}
+
+function min2(a, b) {
+ return a < b ? a : b;
+}
+
+function max2(a, b) {
+ return a > b ? a : b;
+}
+
+function levenshteinDistance(s1, s2) {
+ let len1 = s1.length;
+ let len2 = s2.length;
+
+ if (len1 === 0) return len2;
+ if (len2 === 0) return len1;
+
+ if (len2 > len1) {
+ [s1, s2] = [s2, s1];
+ [len1, len2] = [len2, len1];
+ }
+
+ let prev = new Array(len2 + 1);
+ let curr = new Array(len2 + 1);
+
+ for (let j = 0; j <= len2; j++) {
+ prev[j] = j;
+ }
+
+ for (let i = 1; i <= len1; i++) {
+ curr[0] = i;
+ for (let j = 1; j <= len2; j++) {
+ let cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
+ curr[j] = min3(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost);
+ }
+ [prev, curr] = [curr, prev];
+ }
+
+ return prev[len2];
+}
+
+function partialRatio(shortS, longS) {
+ let lenS = shortS.length;
+ let lenL = longS.length;
+ let best = 0.0;
+
+ if (lenS === 0) return 1.0;
+
+ for (let i = 0; i <= lenL - lenS; i++) {
+ let sub = longS.slice(i, i + lenS);
+ let dist = levenshteinDistance(shortS, sub);
+ let score = 1.0 - (dist / lenS);
+ if (score > best) best = score;
+ }
+
+ return best;
+}
+
+function computeScore(s1, s2) {
+ if (s1 === s2) return 1.0;
+
+ let dist = levenshteinDistance(s1, s2);
+ let maxLen = max2(s1.length, s2.length);
+ if (maxLen === 0) return 1.0;
+
+ let full = 1.0 - (dist / maxLen);
+ let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1);
+
+ let score = 0.85 * full + 0.15 * part;
+
+ if (s1 && s2 && s1[0] !== s2[0]) {
+ score -= 0.05;
+ }
+
+ let lenDiff = Math.abs(s1.length - s2.length);
+ if (lenDiff >= 3) {
+ score -= 0.05 * lenDiff / maxLen;
+ }
+
+ let commonPrefixLen = 0;
+ let minLen = min2(s1.length, s2.length);
+ for (let i = 0; i < minLen; i++) {
+ if (s1[i] === s2[i]) {
+ commonPrefixLen++;
+ } else {
+ break;
+ }
+ }
+ score += 0.02 * commonPrefixLen;
+
+ if (s1.includes(s2) || s2.includes(s1)) {
+ score += 0.06;
+ }
+
+ return Math.max(0.0, Math.min(1.0, score));
+}
+
+function computeTextMatchScore(s1, s2) {
+ if (s1 === s2) return 1.0;
+
+ let dist = levenshteinDistance(s1, s2);
+ let maxLen = max2(s1.length, s2.length);
+ if (maxLen === 0) return 1.0;
+
+ let full = 1.0 - (dist / maxLen);
+ let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1);
+
+ let score = 0.4 * full + 0.6 * part;
+
+ let lenDiff = Math.abs(s1.length - s2.length);
+ if (lenDiff >= 10) {
+ score -= 0.02 * lenDiff / maxLen;
+ }
+
+ let commonPrefixLen = 0;
+ let minLen = min2(s1.length, s2.length);
+ for (let i = 0; i < minLen; i++) {
+ if (s1[i] === s2[i]) {
+ commonPrefixLen++;
+ } else {
+ break;
+ }
+ }
+ score += 0.01 * commonPrefixLen;
+
+ if (s1.includes(s2) || s2.includes(s1)) {
+ score += 0.2;
+ }
+
+ return Math.max(0.0, Math.min(1.0, score));
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage