zadjii-msft / PowerToys

Windows system utilities to maximize productivity
MIT License
3 stars 2 forks source link

Investigate scoring results and giving extensions (and core) scenarios in easy way to rank results #127

Closed joadoumie closed 1 week ago

joadoumie commented 3 weeks ago

Right now, PT Run has the concept of results that can be ranked and scored so that when a user goes back to a specific result or item, it will show up more prominently in the search.

We should work on offering the same value here.

zadjii-msft commented 3 weeks ago

I mean, the extension totally controls the order of results, right? Isn't the "scoring" just "the order the extension hands IListItem's back in?

joadoumie commented 3 weeks ago

Yes that's true -- but it's largely abstracted away in Wox land. Here is an example from the Windows Settings PowerToys plugin:

   /// <summary>
   /// Set the score (known as order number or ranking number)
   /// for all <see cref="Results"/> in the given list, based on the given query.
   /// </summary>
   /// <param name="resultList">A list with <see cref="Result"/>s that need scores.</param>
   /// <param name="query">The query to calculated the score for the <see cref="Result"/>s.</param>
   private static void SetScores(IEnumerable<Result> resultList, string query)
   {
       var lowScore = 1_000;
       var mediumScore = 5_000;
       var highScore = 10_000;
       var firstResultScore = 10_500;

       foreach (var result in resultList)
       {
           if (!(result.ContextData is WindowsSetting windowsSetting))
           {
               continue;
           }

           if (!string.IsNullOrWhiteSpace(query))
           {
               if (windowsSetting.Name.StartsWith(query, StringComparison.CurrentCultureIgnoreCase))
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? highScore-- : firstResultScore--;
                   continue;
               }

               // If query starts with second or next word of name, set score.
               if (windowsSetting.Name.Contains($" {query}", StringComparison.CurrentCultureIgnoreCase))
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? mediumScore-- : firstResultScore--;
                   continue;
               }

               if (windowsSetting.Areas is null)
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? lowScore-- : firstResultScore--;
                   continue;
               }

               if (windowsSetting.Areas.Any(x => x.StartsWith(query, StringComparison.CurrentCultureIgnoreCase)))
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? lowScore-- : firstResultScore--;
                   continue;
               }

               if (windowsSetting.AltNames is null)
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? lowScore-- : firstResultScore--;
                   continue;
               }

               if (windowsSetting.AltNames.Any(x => x.StartsWith(query, StringComparison.CurrentCultureIgnoreCase)))
               {
                   result.Score = !windowsSetting.ShowAsFirstResult ? mediumScore-- : firstResultScore--;
                   continue;
               }
           }

           // On empty queries
           result.Score = !windowsSetting.ShowAsFirstResult ? lowScore-- : firstResultScore--;
       }
   }

The more I think about it, the less certain I am about what extent we should make scoring as easy as possible. It's something worth investigating based on feedback though because it's doable today and all you have to do is set a score? I still need to better understand exactly how this works under the hood.

zadjii-msft commented 1 week ago

I'm gonna reject this as "already possible". The Wox plugins might be setting a score to let Wox then order things by score, but IMO that's also something that apps can just do themselves.

If you've got existing Wox plugins that return a list of results, then just do a results.OrderByDescending(r => r.Score).ToArray() when returning the list out of GetItems

joadoumie commented 1 week ago

I wanna double check whether or not the changes are persistent after reboots for scoring for the existing plugins. I believe they are which is interesting.

I'm gonna keep closed but assign to me so I can filter for it later.