summaryrefslogtreecommitdiff
path: root/utils/levendist.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-08-05 17:25:30 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-08-05 17:25:30 +0800
commitf9efa56caeeb5289d6b2314e50041a1b7055a3c8 (patch)
tree8a9e5b59f8690555ba8ad51f653db02d9483e2a7 /utils/levendist.js
parentf6b5ac3cfba03602fea9d8c30b13075514dbd131 (diff)
feat: add launcher support and image clipboard history utility
- Integrated a new Launcher component into the shell.qml for improved application launching. - Implemented an IPC handler to toggle the launcher visibility. - Added a new script (cliphist-img.sh) to manage image history from the clipboard. - Removed the outdated fuzzysort.js utility to streamline the codebase. - Refactored the Levenshtein distance algorithm for better performance and clarity.
Diffstat (limited to 'utils/levendist.js')
-rw-r--r--utils/levendist.js325
1 files changed, 228 insertions, 97 deletions
diff --git a/utils/levendist.js b/utils/levendist.js
index ed8a5d8..6565e0a 100644
--- a/utils/levendist.js
+++ b/utils/levendist.js
@@ -1,142 +1,273 @@
-// Original code from https://github.com/koeqaife/hyprland-material-you
-// Original code license: GPLv3
-// Translated to Js from Cython with an LLM and reviewed
+var peq = new Uint32Array(0x10000);
-function min3(a, b, c) {
- return a < b && a < c ? a : b < c ? b : c;
-}
+var myers_32 = function(a, b) {
-function max3(a, b, c) {
- return a > b && a > c ? a : b > c ? b : c;
-}
+ var n = a.length;
-function min2(a, b) {
- return a < b ? a : b;
-}
+ var m = b.length;
-function max2(a, b) {
- return a > b ? a : b;
-}
+ var lst = 1 << (n - 1);
-function levenshteinDistance(s1, s2) {
- let len1 = s1.length;
- let len2 = s2.length;
+ var pv = -1;
- if (len1 === 0) return len2;
- if (len2 === 0) return len1;
+ var mv = 0;
- if (len2 > len1) {
- [s1, s2] = [s2, s1];
- [len1, len2] = [len2, len1];
- }
+ var sc = n;
+
+ var i = n;
- let prev = new Array(len2 + 1);
- let curr = new Array(len2 + 1);
+ while (i--) {
+
+ peq[a.charCodeAt(i)] |= 1 << i;
- 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);
+ for (i = 0; i < m; i++) {
+
+ var eq = peq[b.charCodeAt(i)];
+
+ var xv = eq | mv;
+
+ eq |= ((eq & pv) + pv) ^ pv;
+
+ mv |= ~(eq | pv);
+
+ pv &= eq;
+
+ if (mv & lst) {
+
+ sc++;
+
+ }
+
+ if (pv & lst) {
+
+ sc--;
+
}
- [prev, curr] = [curr, prev];
+
+ mv = (mv << 1) | 1;
+
+ pv = (pv << 1) | ~(xv | mv);
+
+ mv &= xv;
+
}
- return prev[len2];
-}
+ i = n;
-function partialRatio(shortS, longS) {
- let lenS = shortS.length;
- let lenL = longS.length;
- let best = 0.0;
+ while (i--) {
- if (lenS === 0) return 1.0;
+ peq[a.charCodeAt(i)] = 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;
-}
+ return sc;
+
+};
+
+var myers_x = function(b, a) {
+
+ var n = a.length;
-function computeScore(s1, s2) {
- if (s1 === s2) return 1.0;
+ var m = b.length;
- let dist = levenshteinDistance(s1, s2);
- let maxLen = max2(s1.length, s2.length);
- if (maxLen === 0) return 1.0;
+ var mhc = [];
- let full = 1.0 - (dist / maxLen);
- let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1);
+ var phc = [];
- let score = 0.85 * full + 0.15 * part;
+ var hsize = Math.ceil(n / 32);
+
+ var vsize = Math.ceil(m / 32);
+
+ for (var i = 0; i < hsize; i++) {
+
+ phc[i] = -1;
+
+ mhc[i] = 0;
- 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;
+ var j = 0;
+
+ for (; j < vsize - 1; j++) {
+
+ var mv_1 = 0;
+
+ var pv_1 = -1;
+
+ var start_1 = j * 32;
+
+ var vlen_1 = Math.min(32, m) + start_1;
+
+ for (var k = start_1; k < vlen_1; k++) {
+
+ peq[b.charCodeAt(k)] |= 1 << k;
+
+ }
+
+ for (var i = 0; i < n; i++) {
+
+ var eq = peq[a.charCodeAt(i)];
+
+ var pb = (phc[(i / 32) | 0] >>> i) & 1;
+
+ var mb = (mhc[(i / 32) | 0] >>> i) & 1;
+
+ var xv = eq | mv_1;
+
+ var xh = ((((eq | mb) & pv_1) + pv_1) ^ pv_1) | eq | mb;
+
+ var ph = mv_1 | ~(xh | pv_1);
+
+ var mh = pv_1 & xh;
+
+ if ((ph >>> 31) ^ pb) {
+
+ phc[(i / 32) | 0] ^= 1 << i;
+
+ }
+
+ if ((mh >>> 31) ^ mb) {
+
+ mhc[(i / 32) | 0] ^= 1 << i;
+
+ }
+
+ ph = (ph << 1) | pb;
+
+ mh = (mh << 1) | mb;
+
+ pv_1 = mh | ~(xv | ph);
+
+ mv_1 = ph & xv;
+
+ }
+
+ for (var k = start_1; k < vlen_1; k++) {
+
+ peq[b.charCodeAt(k)] = 0;
+
+ }
+
+ }
+
+ var mv = 0;
+
+ var pv = -1;
+
+ var start = j * 32;
+
+ var vlen = Math.min(32, m - start) + start;
+
+ for (var k = start; k < vlen; k++) {
+
+ peq[b.charCodeAt(k)] |= 1 << k;
+
}
- 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;
+ var score = m;
+
+ for (var i = 0; i < n; i++) {
+
+ var eq = peq[a.charCodeAt(i)];
+
+ var pb = (phc[(i / 32) | 0] >>> i) & 1;
+
+ var mb = (mhc[(i / 32) | 0] >>> i) & 1;
+
+ var xv = eq | mv;
+
+ var xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;
+
+ var ph = mv | ~(xh | pv);
+
+ var mh = pv & xh;
+
+ score += (ph >>> (m - 1)) & 1;
+
+ score -= (mh >>> (m - 1)) & 1;
+
+ if ((ph >>> 31) ^ pb) {
+
+ phc[(i / 32) | 0] ^= 1 << i;
+
+ }
+
+ if ((mh >>> 31) ^ mb) {
+
+ mhc[(i / 32) | 0] ^= 1 << i;
+
}
+
+ ph = (ph << 1) | pb;
+
+ mh = (mh << 1) | mb;
+
+ pv = mh | ~(xv | ph);
+
+ mv = ph & xv;
+
}
- score += 0.02 * commonPrefixLen;
- if (s1.includes(s2) || s2.includes(s1)) {
- score += 0.06;
+ for (var k = start; k < vlen; k++) {
+
+ peq[b.charCodeAt(k)] = 0;
+
}
- return Math.max(0.0, Math.min(1.0, score));
-}
+ return 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;
+var distance = function(a, b) {
- let full = 1.0 - (dist / maxLen);
- let part = s1.length < s2.length ? partialRatio(s1, s2) : partialRatio(s2, s1);
+ if (a.length < b.length) {
- let score = 0.4 * full + 0.6 * part;
+ var tmp = b;
+
+ b = a;
+
+ a = tmp;
- 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;
- }
+ if (b.length === 0) {
+
+ return a.length;
+
+ }
+
+ if (a.length <= 32) {
+
+ return myers_32(a, b);
+
}
- score += 0.01 * commonPrefixLen;
- if (s1.includes(s2) || s2.includes(s1)) {
- score += 0.2;
+ return myers_x(a, b);
+
+};
+
+var closest = function(str, arr) {
+
+ var min_distance = Infinity;
+
+ var min_index = 0;
+
+ for (var i = 0; i < arr.length; i++) {
+
+ var dist = distance(str, arr[i]);
+
+ if (dist < min_distance) {
+
+ min_distance = dist;
+
+ min_index = i;
+
+ }
+
}
- return Math.max(0.0, Math.min(1.0, score));
-}
+ return arr[min_index];
+};