feat: fzf-like search instead of fuzzy
Also add license for fuzzysort lib
This commit is contained in:
parent
4320904a39
commit
ce26c8a754
8 changed files with 1402 additions and 67 deletions
|
|
@ -1,18 +1,17 @@
|
||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import "root:/utils/scripts/fuzzysort.js" as Fuzzy
|
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.config
|
import qs.config
|
||||||
|
import qs.utils
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
Singleton {
|
Searcher {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string qalcResult
|
property string qalcResult
|
||||||
|
|
||||||
readonly property list<Action> list: [
|
readonly property list<Action> actions: [
|
||||||
Action {
|
Action {
|
||||||
name: qsTr("Calculator")
|
name: qsTr("Calculator")
|
||||||
desc: qsTr("Do simple math equations (powered by Qalc)")
|
desc: qsTr("Do simple math equations (powered by Qalc)")
|
||||||
|
|
@ -134,24 +133,16 @@ Singleton {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
readonly property list<var> preppedActions: list.filter(a => !a.disabled).map(a => ({
|
function transformSearch(search: string): string {
|
||||||
name: Fuzzy.prepare(a.name),
|
return search.slice(Config.launcher.actionPrefix.length);
|
||||||
desc: Fuzzy.prepare(a.desc),
|
|
||||||
action: a
|
|
||||||
}))
|
|
||||||
|
|
||||||
function fuzzyQuery(search: string): var {
|
|
||||||
return Fuzzy.go(search.slice(Config.launcher.actionPrefix.length), preppedActions, {
|
|
||||||
all: true,
|
|
||||||
keys: ["name", "desc"],
|
|
||||||
scoreFn: r => r[0].score > 0 ? r[0].score * 0.9 + r[1].score * 0.1 : 0
|
|
||||||
}).map(r => r.obj.action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function autocomplete(list: AppList, text: string): void {
|
function autocomplete(list: AppList, text: string): void {
|
||||||
list.search.text = `${Config.launcher.actionPrefix}${text} `;
|
list.search.text = `${Config.launcher.actionPrefix}${text} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list: actions.filter(a => !a.disabled)
|
||||||
|
|
||||||
component Action: QtObject {
|
component Action: QtObject {
|
||||||
required property string name
|
required property string name
|
||||||
required property string desc
|
required property string desc
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ StyledListView {
|
||||||
if (isCalc)
|
if (isCalc)
|
||||||
return [0];
|
return [0];
|
||||||
if (isScheme)
|
if (isScheme)
|
||||||
return Schemes.fuzzyQuery(text);
|
return Schemes.query(text);
|
||||||
if (isVariant)
|
if (isVariant)
|
||||||
return M3Variants.fuzzyQuery(text);
|
return M3Variants.query(text);
|
||||||
if (isAction)
|
if (isAction)
|
||||||
return Actions.fuzzyQuery(text);
|
return Actions.query(text);
|
||||||
if (text.startsWith(Config.launcher.actionPrefix))
|
if (text.startsWith(Config.launcher.actionPrefix))
|
||||||
text = search.text.slice(Config.launcher.actionPrefix.length);
|
text = search.text.slice(Config.launcher.actionPrefix.length);
|
||||||
return Apps.fuzzyQuery(text);
|
return Apps.query(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import "root:/utils/scripts/fuzzysort.js" as Fuzzy
|
import qs.utils
|
||||||
import qs.config
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
Singleton {
|
Searcher {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property list<Variant> list: [
|
function transformSearch(search: string): var {
|
||||||
|
return search.slice(`${Config.launcher.actionPrefix}variant `.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
list: [
|
||||||
Variant {
|
Variant {
|
||||||
variant: "vibrant"
|
variant: "vibrant"
|
||||||
icon: "sentiment_very_dissatisfied"
|
icon: "sentiment_very_dissatisfied"
|
||||||
|
|
@ -65,18 +68,6 @@ Singleton {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
readonly property list<var> preppedVariants: list.map(v => ({
|
|
||||||
name: Fuzzy.prepare(v.variant),
|
|
||||||
variant: v
|
|
||||||
}))
|
|
||||||
|
|
||||||
function fuzzyQuery(search: string): var {
|
|
||||||
return Fuzzy.go(search.slice(`${Config.launcher.actionPrefix}variant `.length), preppedVariants, {
|
|
||||||
all: true,
|
|
||||||
key: "name"
|
|
||||||
}).map(r => r.obj.variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
component Variant: QtObject {
|
component Variant: QtObject {
|
||||||
required property string variant
|
required property string variant
|
||||||
required property string icon
|
required property string icon
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,19 @@
|
||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import "root:/utils/scripts/fuzzysort.js" as Fuzzy
|
import qs.utils
|
||||||
import qs.config
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
Singleton {
|
Searcher {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property list<var> preppedSchemes: schemes.instances.map(s => ({
|
function transformSearch(search: string): var {
|
||||||
name: Fuzzy.prepare(s.name),
|
return search.slice(`${Config.launcher.actionPrefix}scheme `.length);
|
||||||
flavour: Fuzzy.prepare(s.flavour),
|
|
||||||
scheme: s
|
|
||||||
}))
|
|
||||||
|
|
||||||
function fuzzyQuery(search: string): var {
|
|
||||||
return Fuzzy.go(search.slice(`${Config.launcher.actionPrefix}scheme `.length), preppedSchemes, {
|
|
||||||
all: true,
|
|
||||||
keys: ["name", "flavour"],
|
|
||||||
scoreFn: r => r[0].score > 0 ? r[0].score * 0.9 + r[1].score * 0.1 : 0
|
|
||||||
}).map(r => r.obj.scheme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list: schemes.instances
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
id: schemes
|
id: schemes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,12 @@
|
||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import "root:/utils/scripts/fuzzysort.js" as Fuzzy
|
import qs.utils
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
|
||||||
Singleton {
|
Searcher {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property list<DesktopEntry> list: DesktopEntries.applications.values.filter(a => !a.noDisplay).sort((a, b) => a.name.localeCompare(b.name))
|
list: DesktopEntries.applications.values.filter(a => !a.noDisplay).sort((a, b) => a.name.localeCompare(b.name))
|
||||||
readonly property list<var> preppedApps: list.map(a => ({
|
|
||||||
name: Fuzzy.prepare(a.name),
|
|
||||||
comment: Fuzzy.prepare(a.comment),
|
|
||||||
entry: a
|
|
||||||
}))
|
|
||||||
|
|
||||||
function fuzzyQuery(search: string): var { // Idk why list<DesktopEntry> doesn't work
|
|
||||||
return Fuzzy.go(search, preppedApps, {
|
|
||||||
all: true,
|
|
||||||
keys: ["name", "comment"],
|
|
||||||
scoreFn: r => r[0].score > 0 ? r[0].score * 0.9 + r[1].score * 0.1 : 0
|
|
||||||
}).map(r => r.obj.entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
function launch(entry: DesktopEntry): void {
|
function launch(entry: DesktopEntry): void {
|
||||||
if (entry.runInTerminal)
|
if (entry.runInTerminal)
|
||||||
|
|
|
||||||
42
utils/Searcher.qml
Normal file
42
utils/Searcher.qml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
import "scripts/fzf.js" as Fzf
|
||||||
|
import "scripts/fuzzysort.js" as Fuzzy
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
required property list<QtObject> list
|
||||||
|
property string key: "name"
|
||||||
|
property bool useFuzzy: false
|
||||||
|
property var extraOpts: ({})
|
||||||
|
|
||||||
|
readonly property var fzf: useFuzzy ? [] : new Fzf.Finder(list, Object.assign({
|
||||||
|
selector: e => e[key]
|
||||||
|
}, extraOpts))
|
||||||
|
readonly property list<var> fuzzyPrepped: useFuzzy ? list.map(e => ({
|
||||||
|
[key]: e[key],
|
||||||
|
_item: e
|
||||||
|
})) : []
|
||||||
|
|
||||||
|
function transformSearch(search: string): string {
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
function query(search: string): list<var> {
|
||||||
|
search = transformSearch(search);
|
||||||
|
if (!search)
|
||||||
|
return [...list];
|
||||||
|
|
||||||
|
if (useFuzzy)
|
||||||
|
return Fuzzy.go(search, fuzzyPrepped, Object.assign({
|
||||||
|
all: true,
|
||||||
|
key
|
||||||
|
}, extraOpts)).map(r => r.obj._item);
|
||||||
|
|
||||||
|
return fzf.find(search).sort((a, b) => {
|
||||||
|
if (a.score === b.score)
|
||||||
|
return a.item[key].trim().length - b.item[key].trim().length;
|
||||||
|
return b.score - a.score;
|
||||||
|
}).map(r => r.item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,31 @@
|
||||||
.pragma library
|
.pragma library
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://github.com/farzher/fuzzysort
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Stephen Kamenar
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
var single = (search, target) => {
|
var single = (search, target) => {
|
||||||
if(!search || !target) return NULL
|
if(!search || !target) return NULL
|
||||||
|
|
||||||
|
|
|
||||||
1307
utils/scripts/fzf.js
Normal file
1307
utils/scripts/fzf.js
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue