CmdPal: Linq clean-up (All Apps) (#41551)

Beginning the process of removing System.Linq from CmdPal. This PR
removes it from the All Apps extension.
This commit is contained in:
Michael Jolley
2025-09-26 11:15:34 -05:00
committed by GitHub
parent 7b7bae2889
commit 3bdb5305ba
17 changed files with 380 additions and 165 deletions

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CmdPal.Ext.Apps.State;
using Microsoft.CommandPalette.Extensions;
@@ -71,26 +71,48 @@ public partial class AllAppsCommandProvider : CommandProvider
{
var items = _page.GetItems();
// We're going to do this search in two directions:
// First, is this name a substring of any app...
var nameMatches = items.Where(i => i.Title.Contains(displayName));
var nameMatches = new List<ICommandItem>();
ICommandItem? bestAppMatch = null;
var bestLength = -1;
// ... Then, does any app have this name as a substring ...
// Only get one of these - "Terminal Preview" contains both "Terminal" and "Terminal Preview", so just take the best one
var appMatches = items.Where(i => displayName.Contains(i.Title)).OrderByDescending(i => i.Title.Length).Take(1);
foreach (var item in items)
{
if (item.Title is null)
{
continue;
}
// We're going to do this search in two directions:
// First, is this name a substring of any app...
if (item.Title.Contains(displayName))
{
nameMatches.Add(item);
}
// ... Then, does any app have this name as a substring ...
// Only get one of these - "Terminal Preview" contains both "Terminal" and "Terminal Preview", so just take the best one
if (displayName.Contains(item.Title))
{
if (item.Title.Length > bestLength)
{
bestLength = item.Title.Length;
bestAppMatch = item;
}
}
}
// ... Now, combine those two
var both = nameMatches.Concat(appMatches);
List<ICommandItem> both = bestAppMatch is null ? nameMatches : [.. nameMatches, bestAppMatch];
if (both.Count() == 1)
if (both.Count == 1)
{
return both.First();
return both[0];
}
else if (nameMatches.Count() == 1 && appMatches.Count() == 1)
else if (nameMatches.Count == 1 && bestAppMatch is not null)
{
if (nameMatches.First() == appMatches.First())
if (nameMatches[0] == bestAppMatch)
{
return nameMatches.First();
return nameMatches[0];
}
}

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ManagedCommon;
@@ -62,7 +61,9 @@ public sealed partial class AllAppsPage : ListPage
{
// Build or update the list if needed
BuildListItems();
return pinnedApps.Concat(unpinnedApps).ToArray();
AppListItem[] allApps = [.. pinnedApps, .. unpinnedApps];
return allApps;
}
private void BuildListItems()
@@ -93,16 +94,25 @@ public sealed partial class AllAppsPage : ListPage
private AppItem[] GetAllApps()
{
var uwpResults = _appCache.UWPs
.Where((application) => application.Enabled)
.Select(app => app.ToAppItem());
List<AppItem> allApps = new();
var win32Results = _appCache.Win32s
.Where((application) => application.Enabled && application.Valid)
.Select(app => app.ToAppItem());
foreach (var uwpApp in _appCache.UWPs)
{
if (uwpApp.Enabled)
{
allApps.Add(uwpApp.ToAppItem());
}
}
var allApps = uwpResults.Concat(win32Results).ToArray();
return allApps;
foreach (var win32App in _appCache.Win32s)
{
if (win32App.Enabled && win32App.Valid)
{
allApps.Add(win32App.ToAppItem());
}
}
return [.. allApps];
}
internal (AppItem[] AllApps, AppListItem[] PinnedItems, AppListItem[] UnpinnedItems) GetPrograms()
@@ -118,9 +128,7 @@ public sealed partial class AllAppsPage : ListPage
if (isPinned)
{
appListItem.Tags = appListItem.Tags
.Concat([new Tag() { Icon = Icons.PinIcon }])
.ToArray();
appListItem.Tags = [.. appListItem.Tags, new Tag() { Icon = Icons.PinIcon }];
pinned.Add(appListItem);
}
else
@@ -129,15 +137,14 @@ public sealed partial class AllAppsPage : ListPage
}
}
pinned.Sort((a, b) => string.Compare(a.Title, b.Title, StringComparison.Ordinal));
unpinned.Sort((a, b) => string.Compare(a.Title, b.Title, StringComparison.Ordinal));
return (
allApps
.ToArray(),
pinned
.OrderBy(app => app.Title)
.ToArray(),
unpinned
.OrderBy(app => app.Title)
.ToArray());
allApps,
pinned.ToArray(),
unpinned.ToArray()
);
}
private void OnPinStateChanged(object? sender, PinStateChangedEventArgs e)
@@ -147,44 +154,55 @@ public sealed partial class AllAppsPage : ListPage
* So, instead, we'll just compare pinned items to move existing
* items between the two lists.
*/
var existingAppItem = allApps.FirstOrDefault(f => f.AppIdentifier == e.AppIdentifier);
AppItem? existingAppItem = null;
foreach (var app in allApps)
{
if (app.AppIdentifier == e.AppIdentifier)
{
existingAppItem = app;
break;
}
}
if (existingAppItem is not null)
{
var appListItem = new AppListItem(existingAppItem, true, e.IsPinned);
var newPinned = new List<AppListItem>(pinnedApps);
var newUnpinned = new List<AppListItem>(unpinnedApps);
if (e.IsPinned)
{
// Remove it from the unpinned apps array
this.unpinnedApps = this.unpinnedApps
.Where(app => app.AppIdentifier != existingAppItem.AppIdentifier)
.OrderBy(app => app.Title)
.ToArray();
var newPinned = this.pinnedApps.ToList();
newPinned.Add(appListItem);
this.pinnedApps = newPinned
.OrderBy(app => app.Title)
.ToArray();
foreach (var app in newUnpinned)
{
if (app.AppIdentifier == e.AppIdentifier)
{
newUnpinned.Remove(app);
break;
}
}
}
else
{
// Remove it from the pinned apps array
this.pinnedApps = this.pinnedApps
.Where(app => app.AppIdentifier != existingAppItem.AppIdentifier)
.OrderBy(app => app.Title)
.ToArray();
var newUnpinned = this.unpinnedApps.ToList();
newUnpinned.Add(appListItem);
this.unpinnedApps = newUnpinned
.OrderBy(app => app.Title)
.ToArray();
foreach (var app in newPinned)
{
if (app.AppIdentifier == e.AppIdentifier)
{
newPinned.Remove(app);
break;
}
}
}
RaiseItemsChanged(0);
pinnedApps = newPinned.ToArray();
unpinnedApps = newUnpinned.ToArray();
}
RaiseItemsChanged(0);
}
}

View File

@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Apps.Programs;
using Microsoft.CmdPal.Ext.Apps.Storage;
@@ -31,7 +30,10 @@ public sealed partial class AppCache : IAppCache, IDisposable
public AppCache()
{
_win32ProgramRepositoryHelper = new Win32ProgramFileSystemWatchers();
_win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast<IFileSystemWatcherWrapper>().ToList(), AllAppsSettings.Instance, _win32ProgramRepositoryHelper.PathsToWatch);
var watchers = new List<IFileSystemWatcherWrapper>(_win32ProgramRepositoryHelper.FileSystemWatchers);
_win32ProgramRepository = new Win32ProgramRepository(watchers, AllAppsSettings.Instance, _win32ProgramRepositoryHelper.PathsToWatch);
_packageRepository = new PackageRepository(new PackageCatalogWrapper());

View File

@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Apps.Programs;
namespace Microsoft.CmdPal.Ext.Apps;

View File

@@ -2,12 +2,8 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Apps.State;
namespace Microsoft.CmdPal.Ext.Apps;

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using Windows.Management.Deployment;
@@ -26,9 +25,19 @@ public class PackageManagerWrapper : IPackageManager
{
var pkgs = _packageManager.FindPackagesForUser(user.Value);
return pkgs.Select(PackageWrapper.GetWrapperFromPackage).Where(package => package is not null);
ICollection<IPackage> packages = [];
foreach (var package in pkgs)
{
if (package is not null)
{
packages.Add(PackageWrapper.GetWrapperFromPackage(package));
}
}
return packages;
}
return Enumerable.Empty<IPackage>();
return [];
}
}

View File

@@ -6,7 +6,6 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using ManagedCommon;
@@ -72,18 +71,20 @@ public partial class UWP
PInvoke.SHCreateStreamOnFileEx(path, STGMREAD, noAttribute, false, null, &stream).ThrowOnFailure();
using var streamHandle = new SafeComHandle((IntPtr)stream);
Apps = AppxPackageHelper.GetAppsFromManifest(stream).Select(appInManifest =>
var appsInManifest = AppxPackageHelper.GetAppsFromManifest(stream);
foreach (var appInManifest in appsInManifest)
{
using var appHandle = new SafeComHandle(appInManifest);
return new UWPApplication((IAppxManifestApplication*)appInManifest, this);
}).Where(a =>
{
var valid =
!string.IsNullOrEmpty(a.UserModelId) &&
!string.IsNullOrEmpty(a.DisplayName) &&
a.AppListEntry != "none";
return valid;
}).ToList();
var uwpApp = new UWPApplication((IAppxManifestApplication*)appInManifest, this);
if (!string.IsNullOrEmpty(uwpApp.UserModelId) &&
!string.IsNullOrEmpty(uwpApp.DisplayName) &&
uwpApp.AppListEntry != "none")
{
Apps.Add(uwpApp);
}
}
}
catch (Exception ex)
{
@@ -93,19 +94,31 @@ public partial class UWP
}
}
// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
private static string[] XmlNamespaces(string path)
{
var z = XDocument.Load(path);
if (z.Root is not null)
{
var namespaces = z.Root.Attributes().
Where(a => a.IsNamespaceDeclaration).
GroupBy(
a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
a => XNamespace.Get(a.Value)).Select(
g => g.First().ToString()).ToArray();
return namespaces;
var namespaces = new HashSet<string>();
var attributes = z.Root.Attributes();
foreach (var attribute in attributes)
{
if (attribute.IsNamespaceDeclaration)
{
// Extract namespace
var key = attribute.Name.Namespace == XNamespace.None ? string.Empty : attribute.Name.LocalName;
XNamespace ns = XNamespace.Get(attribute.Value);
var nsString = ns.ToString();
// Use HashSet to check for duplicates
namespaces.Add(nsString);
}
}
var uniqueNamespaces = new string[namespaces.Count];
namespaces.CopyTo(uniqueNamespaces);
return uniqueNamespaces;
}
else
{
@@ -115,10 +128,13 @@ public partial class UWP
private void InitPackageVersion(string[] namespaces)
{
foreach (var n in _versionFromNamespace.Keys.Where(namespaces.Contains))
foreach (var n in _versionFromNamespace.Keys)
{
Version = _versionFromNamespace[n];
return;
if (Array.IndexOf(namespaces, n) >= 0)
{
Version = _versionFromNamespace[n];
return;
}
}
Version = PackageVersion.Unknown;
@@ -137,7 +153,18 @@ public partial class UWP
foreach (var app in u.Apps)
{
if (AllAppsSettings.Instance.DisabledProgramSources.All(x => x.UniqueIdentifier != app.UniqueIdentifier))
var isDisabled = false;
foreach (var disabled in AllAppsSettings.Instance.DisabledProgramSources)
{
if (disabled.UniqueIdentifier == app.UniqueIdentifier)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
appsBag.Add(app);
}
@@ -154,20 +181,28 @@ public partial class UWP
private static IEnumerable<IPackage> CurrentUserPackages()
{
return PackageManagerWrapper.FindPackagesForCurrentUser().Where(p =>
var currentUsersPackages = PackageManagerWrapper.FindPackagesForCurrentUser();
ICollection<IPackage> packagesToReturn = [];
foreach (var pkg in currentUsersPackages)
{
try
{
var f = p.IsFramework;
var path = p.InstalledLocation;
return !f && !string.IsNullOrEmpty(path);
var f = pkg.IsFramework;
var path = pkg.InstalledLocation;
if (!f && !string.IsNullOrEmpty(path))
{
packagesToReturn.Add(pkg);
}
}
catch (Exception ex)
{
Logger.LogError(ex.Message);
return false;
}
});
}
return packagesToReturn;
}
public override string ToString()

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Xml;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Commands;
@@ -348,20 +347,22 @@ public class UWPApplication : IUWPApplication
//
// FirstOrDefault would result in us using the 1x scaled icon
// always, which is usually too small for our needs.
var selectedIconPath = paths.LastOrDefault(File.Exists);
if (!string.IsNullOrEmpty(selectedIconPath))
for (var i = paths.Count - 1; i >= 0; i--)
{
LogoPath = selectedIconPath;
if (highContrast)
if (File.Exists(paths[i]))
{
LogoType = LogoType.HighContrast;
}
else
{
LogoType = LogoType.Colored;
}
LogoPath = paths[i];
if (highContrast)
{
LogoType = LogoType.HighContrast;
}
else
{
LogoType = LogoType.Colored;
}
return true;
return true;
}
}
}
@@ -402,7 +403,23 @@ public class UWPApplication : IUWPApplication
}
}
var selectedIconPath = paths.OrderBy(x => Math.Abs(pathFactorPairs.GetValueOrDefault(x) - appIconSize)).FirstOrDefault(File.Exists);
// Sort paths by distance to desired app icon size
var selectedIconPath = string.Empty;
var closestDistance = int.MaxValue;
foreach (var p in paths)
{
if (File.Exists(p) && pathFactorPairs.TryGetValue(p, out var factor))
{
var distance = Math.Abs(factor - appIconSize);
if (distance < closestDistance)
{
closestDistance = distance;
selectedIconPath = p;
}
}
}
if (!string.IsNullOrEmpty(selectedIconPath))
{
LogoPath = selectedIconPath;

View File

@@ -7,7 +7,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Security;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -616,9 +615,24 @@ public class Win32Program : IProgram
}
private static IEnumerable<string> CustomProgramPaths(IEnumerable<ProgramSource> sources, IList<string> suffixes)
=> sources?.Where(programSource => Directory.Exists(programSource.Location) && programSource.Enabled)
.SelectMany(programSource => ProgramPaths(programSource.Location, suffixes))
.ToList() ?? Enumerable.Empty<string>();
{
if (sources is not null)
{
var paths = new List<string>();
foreach (var programSource in sources)
{
if (Directory.Exists(programSource.Location) && programSource.Enabled)
{
paths.AddRange(ProgramPaths(programSource.Location, suffixes));
}
}
return paths;
}
return [];
}
// Function to obtain the list of applications, the locations of which have been added to the env variable PATH
private static List<string> PathEnvironmentProgramPaths(IList<string> suffixes)
@@ -647,9 +661,15 @@ public class Win32Program : IProgram
}
private static List<string> IndexPath(IList<string> suffixes, List<string> indexLocations)
=> indexLocations
.SelectMany(indexLocation => ProgramPaths(indexLocation, suffixes))
.ToList();
{
var paths = new List<string>();
foreach (var indexLocation in indexLocations)
{
paths.AddRange(ProgramPaths(indexLocation, suffixes));
}
return paths;
}
private static List<string> StartMenuProgramPaths(IList<string> suffixes)
{
@@ -691,17 +711,51 @@ public class Win32Program : IProgram
}
}
return paths
.Where(path => suffixes.Any(suffix => path.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase)))
.Select(ExpandEnvironmentVariables)
.Where(path => path is not null)
.ToList();
var returnedPaths = new List<string>();
foreach (var path in paths)
{
var matchesSuffix = false;
foreach (var suffix in suffixes)
{
if (path.EndsWith(suffix, StringComparison.InvariantCultureIgnoreCase))
{
matchesSuffix = true;
break;
}
}
if (matchesSuffix)
{
var expandedPath = ExpandEnvironmentVariables(path);
if (expandedPath is not null)
{
returnedPaths.Add(expandedPath);
}
}
}
return returnedPaths;
}
private static IEnumerable<string> GetPathsFromRegistry(RegistryKey root)
=> root
.GetSubKeyNames()
.Select(x => GetPathFromRegistrySubkey(root, x));
{
var result = new List<string>();
// Get all subkey names
var subKeyNames = root.GetSubKeyNames();
// Process each subkey to extract the path
foreach (var subkeyName in subKeyNames)
{
var path = GetPathFromRegistrySubkey(root, subkeyName);
if (!string.IsNullOrEmpty(path))
{
result.Add(path);
}
}
return result;
}
private static string GetPathFromRegistrySubkey(RegistryKey root, string subkey)
{
@@ -765,7 +819,28 @@ public class Win32Program : IProgram
}
public static List<Win32Program> DeduplicatePrograms(IEnumerable<Win32Program> programs)
=> new HashSet<Win32Program>(programs, Win32ProgramEqualityComparer.Default).ToList();
{
// Create a HashSet with the custom equality comparer to automatically deduplicate programs
var uniquePrograms = new HashSet<Win32Program>(Win32ProgramEqualityComparer.Default);
// Filter out invalid programs and add valid ones to the HashSet
foreach (var program in programs)
{
if (program?.Valid == true)
{
uniquePrograms.Add(program);
}
}
// Convert the HashSet to a List for return
var result = new List<Win32Program>(uniquePrograms.Count);
foreach (var program in uniquePrograms)
{
result.Add(program);
}
return result;
}
private static Win32Program GetProgramFromPath(string path)
{
@@ -881,8 +956,22 @@ public class Win32Program : IProgram
foreach (var path in source.GetPaths())
{
if (disabledProgramsList.All(x => x.UniqueIdentifier != path) &&
!ExecutableApplicationExtensions.Contains(Extension(path)))
if (ExecutableApplicationExtensions.Contains(Extension(path)))
{
continue;
}
var isDisabled = false;
foreach (var disabledProgram in disabledProgramsList)
{
if (disabledProgram.UniqueIdentifier == path)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
pathBag.Add(path);
}
@@ -902,7 +991,17 @@ public class Win32Program : IProgram
foreach (var path in source.GetPaths())
{
if (disabledProgramsList.All(x => x.UniqueIdentifier != path))
var isDisabled = false;
foreach (var disabledProgram in disabledProgramsList)
{
if (disabledProgram.UniqueIdentifier == path)
{
isDisabled = true;
break;
}
}
if (!isDisabled)
{
runCommandPathBag.Add(path);
}
@@ -931,10 +1030,8 @@ public class Win32Program : IProgram
}
});
var programs = programsList.ToList();
var runCommandPrograms = runCommandProgramsList.ToList();
return DeduplicatePrograms(programs.Concat(runCommandPrograms).Where(program => program?.Valid == true));
List<Win32Program> allPrograms = [.. programsList, .. runCommandProgramsList];
return DeduplicatePrograms(allPrograms);
}
catch (Exception e)
{

View File

@@ -3,10 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CmdPal.Ext.Apps.State;

View File

@@ -3,9 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using ManagedCommon;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -31,7 +29,7 @@ public sealed class PinnedAppsManager
public bool IsAppPinned(string appIdentifier)
{
return _pinnedApps.PinnedAppIdentifiers.Contains(appIdentifier, StringComparer.OrdinalIgnoreCase);
return _pinnedApps.PinnedAppIdentifiers.IndexOf(appIdentifier) >= 0;
}
public void PinApp(string appIdentifier)

View File

@@ -6,7 +6,6 @@ using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
@@ -20,7 +19,16 @@ public class ListRepository<T> : IRepository<T>, IEnumerable<T>
{
public IList<T> Items
{
get { return _items.Values.ToList(); }
get
{
var items = new List<T>(_items.Count);
foreach (var item in _items.Values)
{
items.Add(item);
}
return items;
}
}
private ConcurrentDictionary<int, T> _items = new ConcurrentDictionary<int, T>();
@@ -34,9 +42,16 @@ public class ListRepository<T> : IRepository<T>, IEnumerable<T>
// enforce that internal representation
try
{
var result = new ConcurrentDictionary<int, T>();
foreach (var item in list)
{
#pragma warning disable CS8602 // Dereference of a possibly null reference.
_items = new ConcurrentDictionary<int, T>(list.ToDictionary(i => i.GetHashCode()));
result.TryAdd(item.GetHashCode(), item);
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}
_items = result;
}
catch (ArgumentException ex)
{

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Programs;
using Microsoft.CmdPal.Ext.Apps.Utils;
@@ -104,10 +103,14 @@ internal sealed partial class PackageRepository : ListRepository<IUWPApplication
// find apps associated with this package.
var packageWrapper = PackageWrapper.GetWrapperFromPackage(package);
var uwp = new UWP(packageWrapper);
var apps = Items.Where(a => a.Package.Equals(uwp)).ToArray();
foreach (var app in apps)
foreach (var app in Items)
{
if (!app.Package.Equals(uwp))
{
continue;
}
Remove(app);
_isDirty = true;
}

View File

@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
@@ -55,7 +54,16 @@ internal sealed partial class Win32ProgramFileSystemWatchers : IDisposable
}
}
return paths.Except(invalidPaths).ToArray();
var validPaths = new List<string>();
foreach (var path in paths)
{
if (!invalidPaths.Contains(path))
{
validPaths.Add(path);
}
}
return validPaths.ToArray();
}
public void Dispose()

View File

@@ -2,10 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
namespace Microsoft.CmdPal.Ext.Apps.Utils;

View File

@@ -2,12 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
public enum Theme

View File

@@ -4,7 +4,6 @@
using System;
using System.Globalization;
using System.Linq;
using Microsoft.Win32;
@@ -56,15 +55,25 @@ public static class ThemeHelper
return Theme.Light; // Default to light theme if missing
}
var theme = themePath.Split('\\').Last().Split('.').First().ToLowerInvariant();
return theme switch
var splitThemePath = themePath.Split('\\');
if (splitThemePath.Length > 0)
{
"hc1" => Theme.HighContrastOne,
"hc2" => Theme.HighContrastTwo,
"hcwhite" => Theme.HighContrastWhite,
"hcblack" => Theme.HighContrastBlack,
_ => Theme.Light,
};
var lastSegment = splitThemePath[splitThemePath.Length - 1];
var splitSegment = lastSegment.Split('.');
if (splitSegment.Length > 0)
{
var themeVariant = splitSegment[0].ToLowerInvariant();
return themeVariant switch
{
"hc1" => Theme.HighContrastOne,
"hc2" => Theme.HighContrastTwo,
"hcwhite" => Theme.HighContrastWhite,
"hcblack" => Theme.HighContrastBlack,
_ => Theme.Light,
};
}
}
return Theme.Light;
}
}