diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettings.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettings.cs
new file mode 100644
index 0000000000..fecf798215
--- /dev/null
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettings.cs
@@ -0,0 +1,24 @@
+// 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.
+
+#nullable enable
+
+using System.Text.Json.Serialization;
+
+namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
+
+///
+/// Strongly typed application-level settings for the Windows Terminal extension.
+/// These are distinct from the dynamic command palette based settings
+/// and are meant for simple persisted state (e.g. last selections).
+///
+public sealed class AppSettings
+{
+ ///
+ /// Gets or sets the last selected channel identifier for the Windows Terminal extension.
+ /// Empty string when no channel has been selected yet.
+ ///
+ [JsonPropertyName("lastSelectedChannel")]
+ public string LastSelectedChannel { get; set; } = string.Empty;
+}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsJsonContext.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsJsonContext.cs
new file mode 100644
index 0000000000..712970c3eb
--- /dev/null
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsJsonContext.cs
@@ -0,0 +1,15 @@
+// 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.
+
+#nullable enable
+
+using System.Text.Json.Serialization;
+
+namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
+
+[JsonSourceGenerationOptions(WriteIndented = true)]
+[JsonSerializable(typeof(AppSettings))]
+internal sealed partial class AppSettingsJsonContext : JsonSerializerContext
+{
+}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsManager.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsManager.cs
new file mode 100644
index 0000000000..2d5cbbd30c
--- /dev/null
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/AppSettingsManager.cs
@@ -0,0 +1,72 @@
+// 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.
+
+#nullable enable
+
+using System;
+using System.IO;
+using System.Text.Json;
+using ManagedCommon;
+using Microsoft.CommandPalette.Extensions.Toolkit;
+
+namespace Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
+
+#nullable enable
+
+public sealed class AppSettingsManager
+{
+ private const string FileName = "appsettings.json";
+
+ private static string SettingsPath()
+ {
+ var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
+ Directory.CreateDirectory(directory);
+ return Path.Combine(directory, FileName);
+ }
+
+ private readonly string _filePath;
+
+ public AppSettings Current { get; private set; } = new();
+
+ public AppSettingsManager()
+ {
+ _filePath = SettingsPath();
+ Load();
+ }
+
+ public void Load()
+ {
+ try
+ {
+ if (File.Exists(_filePath))
+ {
+ var json = File.ReadAllText(_filePath);
+ var loaded = JsonSerializer.Deserialize(json, AppSettingsJsonContext.Default.AppSettings);
+ if (loaded is not null)
+ {
+ Current = loaded;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ExtensionHost.LogMessage(new LogMessage { Message = ex.ToString() });
+ Logger.LogError("Failed to load app settings", ex);
+ }
+ }
+
+ public void Save()
+ {
+ try
+ {
+ var json = JsonSerializer.Serialize(Current, AppSettingsJsonContext.Default.AppSettings);
+ File.WriteAllText(_filePath, json);
+ }
+ catch (Exception ex)
+ {
+ ExtensionHost.LogMessage(new LogMessage { Message = ex.ToString() });
+ Logger.LogError("Failed to save app settings", ex);
+ }
+ }
+}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/SettingsManager.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/SettingsManager.cs
index d1c8be21f4..38ee476bad 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/SettingsManager.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/SettingsManager.cs
@@ -34,13 +34,21 @@ public class SettingsManager : JsonSettingsManager
Resources.open_quake_description,
false);
+ private readonly ToggleSetting _saveLastSelectedChannel = new(
+ Namespaced(nameof(SaveLastSelectedChannel)),
+ Resources.save_last_selected_channel!,
+ Resources.save_last_selected_channel_description!,
+ false);
+
public bool ShowHiddenProfiles => _showHiddenProfiles.Value;
public bool OpenNewTab => _openNewTab.Value;
public bool OpenQuake => _openQuake.Value;
- internal static string SettingsJsonPath()
+ public bool SaveLastSelectedChannel => _saveLastSelectedChannel.Value;
+
+ private static string SettingsJsonPath()
{
var directory = Utilities.BaseSettingsPath("Microsoft.CmdPal");
Directory.CreateDirectory(directory);
@@ -56,6 +64,7 @@ public class SettingsManager : JsonSettingsManager
Settings.Add(_showHiddenProfiles);
Settings.Add(_openNewTab);
Settings.Add(_openQuake);
+ Settings.Add(_saveLastSelectedChannel);
// Load settings from file upon initialization
LoadSettings();
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/TerminalQuery.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/TerminalQuery.cs
index 0665004018..39b3680470 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/TerminalQuery.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Helpers/TerminalQuery.cs
@@ -61,7 +61,7 @@ public class TerminalQuery : ITerminalQuery
return profiles.OrderBy(p => p.Name);
}
- private IEnumerable GetTerminals()
+ public IEnumerable GetTerminals()
{
var user = WindowsIdentity.GetCurrent().User;
var localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Icons.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Icons.cs
index 57abd2c01d..9d3072f25e 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Icons.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Icons.cs
@@ -6,9 +6,11 @@ using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.WindowsTerminal;
-internal sealed class Icons
+internal static class Icons
{
internal static IconInfo TerminalIcon { get; } = IconHelpers.FromRelativePath("Assets\\WindowsTerminal.svg");
internal static IconInfo AdminIcon { get; } = new IconInfo("\xE7EF"); // Admin icon
+
+ internal static IconInfo FilterIcon { get; } = new IconInfo("\uE71C"); // Funnel icon
}
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Pages/ProfilesListPage.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Pages/ProfilesListPage.cs
index 7e9d2cec31..89bb98ca22 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Pages/ProfilesListPage.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsTerminal/Pages/ProfilesListPage.cs
@@ -2,40 +2,73 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
+
+using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using ManagedCommon;
using Microsoft.CmdPal.Ext.WindowsTerminal.Commands;
using Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
+using Windows.Foundation;
namespace Microsoft.CmdPal.Ext.WindowsTerminal.Pages;
-internal sealed partial class ProfilesListPage : ListPage
+internal sealed partial class ProfilesListPage : ListPage, INotifyItemsChanged
{
+ event TypedEventHandler