diff options
Diffstat (limited to 'src/apps.vala')
-rw-r--r-- | src/apps.vala | 94 |
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)) |