RecentCommandsManager.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Text.Json.Serialization; 6 using CommunityToolkit.Mvvm.ComponentModel; 7 8 namespace Microsoft.CmdPal.UI.ViewModels; 9 10 public partial class RecentCommandsManager : ObservableObject, IRecentCommandsManager 11 { 12 [JsonInclude] 13 internal List<HistoryItem> History { get; set; } = []; 14 15 private readonly Lock _lock = new(); 16 17 public RecentCommandsManager() 18 { 19 } 20 21 public int GetCommandHistoryWeight(string commandId) 22 { 23 lock (_lock) 24 { 25 var entry = History 26 .Index() 27 .Where(item => item.Item.CommandId == commandId) 28 .FirstOrDefault(); 29 30 // These numbers are vaguely scaled so that "VS" will make "Visual Studio" the 31 // match after one use. 32 // Usually it has a weight of 84, compared to 109 for the VS cmd prompt 33 if (entry.Item is not null) 34 { 35 var index = entry.Index; 36 37 // First, add some weight based on how early in the list this appears 38 var bucket = index switch 39 { 40 var i when index <= 2 => 35, 41 var i when index <= 10 => 25, 42 var i when index <= 15 => 15, 43 var i when index <= 35 => 10, 44 _ => 5, 45 }; 46 47 // Then, add weight for how often this is used, but cap the weight from usage. 48 var uses = Math.Min(entry.Item.Uses * 5, 35); 49 50 return bucket + uses; 51 } 52 53 return 0; 54 } 55 } 56 57 public void AddHistoryItem(string commandId) 58 { 59 lock (_lock) 60 { 61 var entry = History 62 .Where(item => item.CommandId == commandId) 63 .FirstOrDefault(); 64 if (entry is null) 65 { 66 var newitem = new HistoryItem() { CommandId = commandId, Uses = 1 }; 67 History.Insert(0, newitem); 68 } 69 else 70 { 71 History.Remove(entry); 72 entry.Uses++; 73 History.Insert(0, entry); 74 } 75 76 if (History.Count > 50) 77 { 78 History.RemoveRange(50, History.Count - 50); 79 } 80 } 81 } 82 } 83 84 public interface IRecentCommandsManager 85 { 86 int GetCommandHistoryWeight(string commandId); 87 88 void AddHistoryItem(string commandId); 89 }