AliasManager.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 CommunityToolkit.Mvvm.ComponentModel; 6 using CommunityToolkit.Mvvm.Messaging; 7 using Microsoft.CmdPal.Core.ViewModels.Messages; 8 9 namespace Microsoft.CmdPal.UI.ViewModels; 10 11 public partial class AliasManager : ObservableObject 12 { 13 private readonly TopLevelCommandManager _topLevelCommandManager; 14 15 // REMEMBER, CommandAlias.SearchPrefix is what we use as keys 16 private readonly Dictionary<string, CommandAlias> _aliases; 17 18 public AliasManager(TopLevelCommandManager tlcManager, SettingsModel settings) 19 { 20 _topLevelCommandManager = tlcManager; 21 _aliases = settings.Aliases; 22 23 if (_aliases.Count == 0) 24 { 25 PopulateDefaultAliases(); 26 } 27 } 28 29 private void AddAlias(CommandAlias a) => _aliases.Add(a.SearchPrefix, a); 30 31 public bool CheckAlias(string searchText) 32 { 33 if (_aliases.TryGetValue(searchText, out var alias)) 34 { 35 try 36 { 37 var topLevelCommand = _topLevelCommandManager.LookupCommand(alias.CommandId); 38 if (topLevelCommand is not null) 39 { 40 WeakReferenceMessenger.Default.Send<ClearSearchMessage>(); 41 42 WeakReferenceMessenger.Default.Send<PerformCommandMessage>(topLevelCommand.GetPerformCommandMessage()); 43 return true; 44 } 45 } 46 catch 47 { 48 } 49 } 50 51 return false; 52 } 53 54 private void PopulateDefaultAliases() 55 { 56 this.AddAlias(new CommandAlias(":", "com.microsoft.cmdpal.registry", true)); 57 this.AddAlias(new CommandAlias("$", "com.microsoft.cmdpal.windowsSettings", true)); 58 this.AddAlias(new CommandAlias("=", "com.microsoft.cmdpal.calculator", true)); 59 this.AddAlias(new CommandAlias(">", "com.microsoft.cmdpal.shell", true)); 60 this.AddAlias(new CommandAlias("<", "com.microsoft.cmdpal.windowwalker", true)); 61 this.AddAlias(new CommandAlias("??", "com.microsoft.cmdpal.websearch", true)); 62 this.AddAlias(new CommandAlias("file", "com.microsoft.indexer.fileSearch", false)); 63 this.AddAlias(new CommandAlias(")", "com.microsoft.cmdpal.timedate", true)); 64 } 65 66 public string? KeysFromId(string commandId) 67 { 68 return _aliases 69 .Where(kv => kv.Value.CommandId == commandId) 70 .Select(kv => kv.Value.Alias) 71 .FirstOrDefault(); 72 } 73 74 public CommandAlias? AliasFromId(string commandId) 75 { 76 return _aliases 77 .Where(kv => kv.Value.CommandId == commandId) 78 .Select(kv => kv.Value) 79 .FirstOrDefault(); 80 } 81 82 public void UpdateAlias(string commandId, CommandAlias? newAlias) 83 { 84 if (string.IsNullOrEmpty(commandId)) 85 { 86 // do nothing? 87 return; 88 } 89 90 // If we already have _this exact alias_, do nothing 91 if (newAlias is not null && 92 _aliases.TryGetValue(newAlias.SearchPrefix, out var existingAlias)) 93 { 94 if (existingAlias.CommandId == commandId) 95 { 96 return; 97 } 98 } 99 100 List<CommandAlias> toRemove = []; 101 foreach (var kv in _aliases) 102 { 103 // Look for the old aliases for the command, and remove it 104 if (kv.Value.CommandId == commandId) 105 { 106 toRemove.Add(kv.Value); 107 } 108 109 // Look for the alias belonging to another command, and remove it 110 if (newAlias is not null && kv.Value.Alias == newAlias.Alias && kv.Value.CommandId != commandId) 111 { 112 toRemove.Add(kv.Value); 113 114 // Remove alias from other TopLevelViewModels it may be assigned to 115 var topLevelCommand = _topLevelCommandManager.LookupCommand(kv.Value.CommandId); 116 if (topLevelCommand is not null) 117 { 118 topLevelCommand.AliasText = string.Empty; 119 } 120 } 121 } 122 123 foreach (var alias in toRemove) 124 { 125 // REMEMBER, SearchPrefix is what we use as keys 126 _aliases.Remove(alias.SearchPrefix); 127 } 128 129 if (newAlias is not null) 130 { 131 AddAlias(newAlias); 132 } 133 } 134 }