summaryrefslogtreecommitdiff
path: root/src/apps.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps.vala')
-rw-r--r--src/apps.vala94
1 files changed, 80 insertions, 14 deletions
diff --git a/src/apps.vala b/src/apps.vala
index a9524b9..2a0d507 100644
--- a/src/apps.vala
+++ b/src/apps.vala
@@ -3,15 +3,27 @@ public class Apps : Object {
private string cache_directory;
private string cache_file;
private List<Application> _list;
- private HashTable<string, uint> frequents { get; private set; }
+ private HashTable<string, int> frequents { get; private set; }
public bool show_hidden { get; set; }
public List<weak Application> list { owned get { return _list.copy(); } }
+ public double min_score { get; set; default = 0.5; }
+
+ public double name_multiplier { get; set; default = 2; }
+ public double entry_multiplier { get; set; default = 1; }
+ public double executable_multiplier { get; set; default = 1; }
+ public double description_multiplier { get; set; default = 0.5; }
+
+ public bool include_name { get; set; default = true; }
+ public bool include_entry { get; set; default = false; }
+ public bool include_executable { get; set; default = false; }
+ public bool include_description { get; set; default = false; }
+
construct {
cache_directory = Environment.get_user_cache_dir() + "/astal";
cache_file = cache_directory + "/apps-frequents.json";
- frequents = new HashTable<string, uint>(str_hash, str_equal);
+ frequents = new HashTable<string, int>(str_hash, str_equal);
AppInfoMonitor.get().changed.connect(() => {
reload();
@@ -27,7 +39,7 @@ public class Apps : Object {
var obj = parser.get_root().get_object();
foreach (var member in obj.get_members()) {
var v = obj.get_member(member).get_value().get_int64();
- frequents.set(member, (uint)v);
+ frequents.set(member, (int)v);
}
} catch (Error err) {
critical("cannot read cache: %s\n", err.message);
@@ -37,23 +49,79 @@ public class Apps : Object {
reload();
}
- private int compare (string search, Application a, Application b) {
- var s1 = a.match(search) * 100;
- var s2 = b.match(search) * 100;
- return (int)s2 - (int)s1;
+ private double score (string search, Application a, bool exact) {
+ var am = exact ? a.exact_match(search) : a.fuzzy_match(search);
+ double r = 0;
+
+ if (include_name)
+ r += am.name * name_multiplier;
+ if (include_entry)
+ r += am.entry * entry_multiplier;
+ if (include_executable)
+ r += am.executable * executable_multiplier;
+ if (include_description)
+ r += am.description * description_multiplier;
+
+ return r;
}
- public List<weak Application> query(string? search = "") {
+ public List<weak Application> query(string? search = "", bool exact = false) {
if (search == null)
- return list.copy();
+ search = "";
var arr = list.copy();
+
+ // empty search, sort by frequency
+ if (search == "") {
+ arr.sort_with_data((a, b) => {
+ return (int)b.frequency - (int)a.frequency;
+ });
+
+ return arr;
+ }
+
+ // single character, sort by frequency and exact match
+ if (search.length == 1) {
+ foreach (var app in list) {
+ if (score(search, app, true) == 0)
+ arr.remove(app);
+ }
+
+ arr.sort_with_data((a, b) => {
+ return (int)b.frequency - (int)a.frequency;
+ });
+
+ return arr;
+ }
+
+ // filter
+ foreach (var app in list) {
+ if (score(search, app, exact) < min_score)
+ arr.remove(app);
+ }
+
+ // sort by score, frequency
arr.sort_with_data((a, b) => {
- return compare(search, a, b);
+ var s1 = score(search, a, exact);
+ var s2 = score(search, b, exact);
+
+ if (s1 == s2)
+ return (int)b.frequency - (int)a.frequency;
+
+ return s1 < s2 ? 1 : -1;
});
+
return arr;
}
+ public List<weak Application> fuzzy_query(string? search = "") {
+ return query(search, false);
+ }
+
+ public List<weak Application> exact_query(string? search = "") {
+ return query(search, true);
+ }
+
public void reload() {
var arr = AppInfo.get_all();
@@ -86,10 +154,8 @@ public class Apps : Object {
private void cache() {
var json = new Json.Builder().begin_object();
- foreach (string key in frequents.get_keys()) {
- uint v = frequents.get(key);
- json.set_member_name(key).add_int_value((int)v);
- }
+ foreach (string key in frequents.get_keys())
+ json.set_member_name(key).add_int_value(frequents.get(key));
try {
if (!FileUtils.test(cache_directory, FileTest.EXISTS))