// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; using Microsoft.CmdPal.Core.ViewModels.Messages; namespace Microsoft.CmdPal.UI.ViewModels; public partial class AliasManager : ObservableObject { private readonly TopLevelCommandManager _topLevelCommandManager; // REMEMBER, CommandAlias.SearchPrefix is what we use as keys private readonly Dictionary _aliases; public AliasManager(TopLevelCommandManager tlcManager, SettingsModel settings) { _topLevelCommandManager = tlcManager; _aliases = settings.Aliases; if (_aliases.Count == 0) { PopulateDefaultAliases(); } } private void AddAlias(CommandAlias a) => _aliases.Add(a.SearchPrefix, a); public bool CheckAlias(string searchText) { if (_aliases.TryGetValue(searchText, out var alias)) { try { var topLevelCommand = _topLevelCommandManager.LookupCommand(alias.CommandId); if (topLevelCommand is not null) { WeakReferenceMessenger.Default.Send(); WeakReferenceMessenger.Default.Send(topLevelCommand.GetPerformCommandMessage()); return true; } } catch { } } return false; } private void PopulateDefaultAliases() { this.AddAlias(new CommandAlias(":", "com.microsoft.cmdpal.registry", true)); this.AddAlias(new CommandAlias("$", "com.microsoft.cmdpal.windowsSettings", true)); this.AddAlias(new CommandAlias("=", "com.microsoft.cmdpal.calculator", true)); this.AddAlias(new CommandAlias(">", "com.microsoft.cmdpal.shell", true)); this.AddAlias(new CommandAlias("<", "com.microsoft.cmdpal.windowwalker", true)); this.AddAlias(new CommandAlias("??", "com.microsoft.cmdpal.websearch", true)); this.AddAlias(new CommandAlias("file", "com.microsoft.indexer.fileSearch", false)); this.AddAlias(new CommandAlias(")", "com.microsoft.cmdpal.timedate", true)); } public string? KeysFromId(string commandId) { return _aliases .Where(kv => kv.Value.CommandId == commandId) .Select(kv => kv.Value.Alias) .FirstOrDefault(); } public CommandAlias? AliasFromId(string commandId) { return _aliases .Where(kv => kv.Value.CommandId == commandId) .Select(kv => kv.Value) .FirstOrDefault(); } public void UpdateAlias(string commandId, CommandAlias? newAlias) { if (string.IsNullOrEmpty(commandId)) { // do nothing? return; } // If we already have _this exact alias_, do nothing if (newAlias is not null && _aliases.TryGetValue(newAlias.SearchPrefix, out var existingAlias)) { if (existingAlias.CommandId == commandId) { return; } } List toRemove = []; foreach (var kv in _aliases) { // Look for the old aliases for the command, and remove it if (kv.Value.CommandId == commandId) { toRemove.Add(kv.Value); } // Look for the alias belonging to another command, and remove it if (newAlias is not null && kv.Value.Alias == newAlias.Alias && kv.Value.CommandId != commandId) { toRemove.Add(kv.Value); // Remove alias from other TopLevelViewModels it may be assigned to var topLevelCommand = _topLevelCommandManager.LookupCommand(kv.Value.CommandId); if (topLevelCommand is not null) { topLevelCommand.AliasText = string.Empty; } } } foreach (var alias in toRemove) { // REMEMBER, SearchPrefix is what we use as keys _aliases.Remove(alias.SearchPrefix); } if (newAlias is not null) { AddAlias(newAlias); } } }