From 2cb0f939e0392f2520b516fad397053d523210c2 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Thu, 7 Aug 2025 17:26:38 +0800 Subject: feat(Launcher): Clip --- services/Clip.qml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'services') diff --git a/services/Clip.qml b/services/Clip.qml index af9ee7b..6fee97c 100644 --- a/services/Clip.qml +++ b/services/Clip.qml @@ -3,6 +3,7 @@ pragma Singleton import Quickshell import Quickshell.Io import QtQuick +import "../utils/levendist.js" as Levendist Singleton { id: root @@ -15,6 +16,8 @@ Singleton { property string toCopy: "" property string decoded: "" + property var fuzzyQueryCache: ({}); + property var clipHist: { const arr = []; if (!_clipHist?.length) @@ -57,6 +60,45 @@ Singleton { return arr; } + function fuzzyQuery(search) { + if (!search) + return root.clipHist; + if (root.fuzzyQueryCache[search]) { + return root.fuzzyQueryCache[search]; + } + let source = root.clipHist; + let previousLists = Object.keys(root.fuzzyQueryCache).filter(key => key && search.startsWith(key)); + if (previousLists.length > 0) { + var longest = previousLists.reduce((a, b) => a.length >= b.length ? a : b); + source = root.fuzzyQueryCache[longest]; + } + const p = [], f = []; + for (const s of source) { + const t = (s.isImage ? "image" : (s.data || "")).toLowerCase(); + if (t.startsWith(search)) { + p.push(s); + continue; + } + let pos = 0; + for (const c of search) { + pos = t.indexOf(c, pos); + if (pos < 0) { + pos = 0; + break; + } + pos++; + } + if (pos) + f.push({ + s, + score: Levendist.distance(search, t) + }); + } + const results = p.concat(f.sort((a, b) => a.score - b.score).map(({s}) => s)); + root.fuzzyQueryCache[search] = results; + return results; + } + component SClip_t: QtObject { property int index property bool isImage -- cgit v1.2.3