diff --git a/QuickShell.Core.Tests/RunGlobalQueryTests.cs b/QuickShell.Core.Tests/RunGlobalQueryTests.cs index 7ae7e340..9188f763 100644 --- a/QuickShell.Core.Tests/RunGlobalQueryTests.cs +++ b/QuickShell.Core.Tests/RunGlobalQueryTests.cs @@ -1,11 +1,7 @@ using QuickShell.Services; - - - + namespace QuickShell.Core.Tests; - - - + public sealed class RunGlobalQueryTests { @@ -29,9 +25,7 @@ public void TryActivate_PluginName_EntersBrowseMode(string query) Assert.Equal(string.Empty, remaining); } - - - + [Fact] public void TryActivate_PluginNameWithFilter_StripsPrefix() @@ -43,9 +37,7 @@ public void TryActivate_PluginNameWithFilter_StripsPrefix() Assert.Equal("api", remaining); } - - - + [Fact] public void TryActivate_RawQueryFallback_ActivatesWhenSearchEmpty() @@ -57,9 +49,7 @@ public void TryActivate_RawQueryFallback_ActivatesWhenSearchEmpty() Assert.Equal(string.Empty, remaining); } - - - + [Fact] public void TryActivate_UnrelatedQuery_DoesNotActivate() @@ -71,9 +61,7 @@ public void TryActivate_UnrelatedQuery_DoesNotActivate() Assert.Equal("my api project", remaining); } - - - + [Fact] public void ShouldSuppressEmptyGlobalQuery_BlocksBareGlobalSearch() @@ -85,9 +73,7 @@ public void ShouldSuppressEmptyGlobalQuery_BlocksBareGlobalSearch() Assert.True(RunGlobalQuery.ShouldSuppressEmptyGlobalQuery(context)); } - - - + [Fact] public void ShouldSuppressEmptyGlobalQuery_AllowsActionKeywordBrowse() diff --git a/QuickShell.Core.Tests/WorkspaceTrustCommandTests.cs b/QuickShell.Core.Tests/WorkspaceTrustCommandTests.cs index 9d388ab3..d79442ce 100644 --- a/QuickShell.Core.Tests/WorkspaceTrustCommandTests.cs +++ b/QuickShell.Core.Tests/WorkspaceTrustCommandTests.cs @@ -105,8 +105,7 @@ private static (QuickShellServices Services, QuickShellLifetime Lifetime, Shortc lifetime); return (services, lifetime, drafts); } - - + private static TerminalShortcut CreateWorkspace() => new() { diff --git a/QuickShell.Core/Models/TerminalShortcut.cs b/QuickShell.Core/Models/TerminalShortcut.cs index 3539314e..7a0bfb9a 100644 --- a/QuickShell.Core/Models/TerminalShortcut.cs +++ b/QuickShell.Core/Models/TerminalShortcut.cs @@ -1,84 +1,52 @@ namespace QuickShell.Models; - - - + internal sealed class TerminalShortcut { public string Id { get; set; } = string.Empty; - - - + public string Name { get; set; } = string.Empty; - - - + public string? Abbreviation { get; set; } - - - + public string Directory { get; set; } = string.Empty; - - - + public string? Command { get; set; } - - - + // "default" means use extension-level default terminal setting. public string Terminal { get; set; } = "default"; - - - + // Optional Windows Terminal profile name for terminal=wt/default->wt. public string? WtProfile { get; set; } - - - + public bool RunAsAdmin { get; set; } - - - + public bool IsPinned { get; set; } - - - + // Lower number means higher in the favorites section. public int? PinOrder { get; set; } - - - + public DateTime? LastUsedUtc { get; set; } - - - + /// One or more terminal launches for this workspace. When empty on disk, synthesized from legacy fields on load. public List Launches { get; set; } = []; - - - + /// Optional dev server URL opened in the browser when the workspace runs. public string? DevServerUrl { get; set; } - - - + /// When true, opens whenever the full workspace runs. public bool OpenDevServerOnLaunch { get; set; } - - - + /// Optional repository URL opened from the workspace action menu. public string? RepoUrl { get; set; } - - - + /// /// One or more GUI companion apps. When empty on disk, synthesized from the legacy /// scalar companion fields on load (see CompanionAppNormalization). diff --git a/QuickShell.Core/Services/ShortcutLaunchFormJson.cs b/QuickShell.Core/Services/ShortcutLaunchFormJson.cs index e1596f14..0ce70243 100644 --- a/QuickShell.Core/Services/ShortcutLaunchFormJson.cs +++ b/QuickShell.Core/Services/ShortcutLaunchFormJson.cs @@ -1,9 +1,7 @@ using QuickShell.Core.Services; namespace QuickShell.Services; - - - + internal static partial class ShortcutLaunchFormJson { @@ -13,35 +11,23 @@ internal static partial class ShortcutLaunchFormJson private const string ProfileColumnWidth = "2"; private const string AdminColumnWidth = "auto"; - - - + public sealed class LaunchRowDraft { public string Label { get; set; } = string.Empty; - - - + public string Command { get; set; } = string.Empty; - - - + public string LaunchTarget { get; set; } = "default"; - - - + public bool RunAsAdmin { get; set; } - - - + public bool IsEnabled { get; set; } = true; } - - - + public static string BuildCommandRowsJson( IReadOnlyList rows, string terminalChoices, @@ -124,9 +110,7 @@ public static string BuildCommandRowsJson( return string.Join(',', blocks); } - - - + public static string BuildCommandsSectionHeaderJson(LaunchEditorText text) => $$""" { @@ -168,9 +152,7 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, return string.Empty; } - - - + var blocks = new List(); for (var i = 0; i < launches.Count; i++) @@ -188,9 +170,7 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, var adminValue = launch.RunAsAdmin ? "true" : "false"; var enabledValue = launch.IsEnabled ? "true" : "false"; - - - + var labelInput = $$""" { @@ -206,13 +186,9 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, } """; - - - + var commandInput = BuildCommandInputWithClear(i, literalValue: escapedCommand, removeTooltip: FormActionGlyphs.ClearCommandTooltip); - - - + var adminInput = $$""" { @@ -232,9 +208,7 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, } """; - - - + var enabledInput = $$""" { @@ -254,9 +228,7 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, } """; - - - + blocks.Add($$""" { @@ -520,21 +492,15 @@ public static string BuildLaunchRowsJson(IReadOnlyList launches, """); } - - - + return string.Join(',', blocks); } - - - + public static string WrapLaunchRowsForTest(string launchRows) => $$"""{ "type": "AdaptiveCard", "version": "1.6", "body": [{{launchRows}}] }"""; - - - + private static string Escape(string? value) => (value ?? string.Empty).Replace("\\", "\\\\").Replace("\"", "\\\""); diff --git a/QuickShell.Core/Services/TerminalCatalog.cs b/QuickShell.Core/Services/TerminalCatalog.cs index a68aaabb..c460e7a1 100644 --- a/QuickShell.Core/Services/TerminalCatalog.cs +++ b/QuickShell.Core/Services/TerminalCatalog.cs @@ -63,8 +63,7 @@ public TerminalCatalog(IWtProfilesService profiles) { _profiles = profiles ?? throw new ArgumentNullException(nameof(profiles)); } - - + string ITerminalCatalog.EncodeLaunchTargetId(TerminalShortcut shortcut) => EncodeLaunchTargetId(shortcut); @@ -87,8 +86,7 @@ WorkspaceEntry ITerminalCatalog.ResolveLaunchEntry( IReadOnlyList orderedLaunches, int index) => ResolveLaunchEntry(entry, orderedLaunches, index); - - + public IReadOnlyList GetLaunchTargets(bool includeDefaultChoice = false) { var snapshot = EnsureCached(); diff --git a/QuickShell.Core/Services/TerminalHostIds.cs b/QuickShell.Core/Services/TerminalHostIds.cs index 1859a3d2..95c20e77 100644 --- a/QuickShell.Core/Services/TerminalHostIds.cs +++ b/QuickShell.Core/Services/TerminalHostIds.cs @@ -1,40 +1,29 @@ namespace QuickShell.Services; - internal static class TerminalHostIds { public const string LetWindowsChoose = "system"; - public const string WindowsTerminal = "wt"; - public const string WindowsConsoleHost = "conhost"; - public const string IntelligentTerminal = "it"; - public const string DefaultProfile = "__default__"; - public static string ResolveEffectiveApplication(string terminalApplicationId) { if (terminalApplicationId.Equals(LetWindowsChoose, StringComparison.OrdinalIgnoreCase)) { return WindowsDefaultTerminalReader.ReadApplicationId(); } - return terminalApplicationId; } - public static bool UsesWindowsTerminalProfiles(string terminalApplicationId) => !ResolveEffectiveApplication(terminalApplicationId) .Equals(WindowsConsoleHost, StringComparison.OrdinalIgnoreCase); - public static bool IsWindowsTerminalProfilePrefix(string idPrefix) => idPrefix.Equals("wt", StringComparison.OrdinalIgnoreCase) || idPrefix.Equals("wtp", StringComparison.OrdinalIgnoreCase) || idPrefix.Equals("wtu", StringComparison.OrdinalIgnoreCase); - public static bool IsSupportedProfilePrefix(string idPrefix) => IsWindowsTerminalProfilePrefix(idPrefix) || idPrefix.Equals(IntelligentTerminal, StringComparison.OrdinalIgnoreCase); - public static string HostExecutable(string terminalApplicationId) { var effective = ResolveEffectiveApplication(terminalApplicationId); @@ -42,7 +31,6 @@ public static string HostExecutable(string terminalApplicationId) ? "wtai.exe" : "wt.exe"; } - public static string ProfileIdPrefix(string terminalApplicationId) { var effective = ResolveEffectiveApplication(terminalApplicationId); @@ -50,19 +38,16 @@ public static string ProfileIdPrefix(string terminalApplicationId) ? IntelligentTerminal : WindowsTerminal; } - public static string SourceLabel(string terminalApplicationId) { if (terminalApplicationId.Equals(LetWindowsChoose, StringComparison.OrdinalIgnoreCase)) { return "Let Windows choose"; } - if (terminalApplicationId.Equals(WindowsConsoleHost, StringComparison.OrdinalIgnoreCase)) { return "Windows Console Host"; } - return ResolveEffectiveApplication(terminalApplicationId).Equals(IntelligentTerminal, StringComparison.OrdinalIgnoreCase) ? "Intelligent Terminal" : "Windows Terminal"; diff --git a/QuickShell.Core/Services/WorkspaceRepositorySnapshot.cs b/QuickShell.Core/Services/WorkspaceRepositorySnapshot.cs index 40517cd6..df2890fb 100644 --- a/QuickShell.Core/Services/WorkspaceRepositorySnapshot.cs +++ b/QuickShell.Core/Services/WorkspaceRepositorySnapshot.cs @@ -244,8 +244,7 @@ private static int ComputeTaskActionScore( ScoreToken(launch.Command, token, exact: 850, prefix: 600, contains: 260) + ScoreToken(profileLabel, token, exact: 250, prefix: 175, contains: 90) + ScoreToken(launch.WtProfile, token, exact: 220, prefix: 160, contains: 80); - - + if (workspaceScore + launchScore == 0) { return 0; diff --git a/QuickShell.Run/QuickShellRunSettingsWindow.cs b/QuickShell.Run/QuickShellRunSettingsWindow.cs index 4455a447..11f549dd 100644 --- a/QuickShell.Run/QuickShellRunSettingsWindow.cs +++ b/QuickShell.Run/QuickShellRunSettingsWindow.cs @@ -5,13 +5,9 @@ using System.Windows; using System.Windows.Controls; - - - + namespace QuickShell.Run; - - - + internal sealed class QuickShellRunSettingsWindow : Window { @@ -37,9 +33,7 @@ internal sealed class QuickShellRunSettingsWindow : Window private readonly TextBlock _statusText; private SettingsSnapshot _baseline; - - - + public QuickShellRunSettingsWindow( QuickShellSettingsReader settings, @@ -71,15 +65,11 @@ public QuickShellRunSettingsWindow( WindowStartupLocation = WindowStartupLocation.CenterScreen; ResizeMode = ResizeMode.NoResize; - - - + var root = new StackPanel { Margin = new Thickness(16) }; root.Children.Add(Heading("Terminal defaults")); - - - + root.Children.Add(Label("Terminal application")); _terminalAppBox = Combo(RunTerminalChoices.GetTerminalApplicationChoices(_catalog)); @@ -87,9 +77,7 @@ public QuickShellRunSettingsWindow( _terminalAppBox.SelectionChanged += (_, _) => ReloadProfileChoices(); root.Children.Add(_terminalAppBox); - - - + root.Children.Add(Label("Default profile")); _defaultProfileBox = new ComboBox @@ -105,9 +93,7 @@ public QuickShellRunSettingsWindow( }; root.Children.Add(_defaultProfileBox); - - - + root.Children.Add(Heading("Git launch")); _blockDirtyBranchBox = new CheckBox @@ -125,9 +111,7 @@ public QuickShellRunSettingsWindow( root.Children.Add(Help( "When a worktree target branch differs from HEAD, block launch if the working tree has uncommitted changes.")); - - - + root.Children.Add(Heading("Home list")); _showRecentsBox = new CheckBox @@ -141,9 +125,7 @@ public QuickShellRunSettingsWindow( }; root.Children.Add(_showRecentsBox); - - - + root.Children.Add(Heading("Multiple commands")); _singleWindowTabsBox = new CheckBox @@ -161,9 +143,7 @@ public QuickShellRunSettingsWindow( root.Children.Add(Help( "When supported, extra commands open as tabs in the same window. Mixed elevation or Console Host still opens separate windows.")); - - - + root.Children.Add(Heading("Shortcuts")); root.Children.Add(TooltipButton( @@ -189,13 +169,9 @@ public QuickShellRunSettingsWindow( "Replace every shortcut with the contents of a JSON file.", () => ImportShortcuts(replace: true))); - - - + root.Children.Add(new Separator { Margin = new Thickness(0, 8, 0, 8) }); - - - + root.Children.Add(TooltipButton( "Open shortcuts.json", @@ -211,9 +187,7 @@ public QuickShellRunSettingsWindow( "Open the folder that stores shortcuts and settings.", () => RunFileDialogs.OpenFolder(_shortcuts.ConfigDirectory))); - - - + _statusText = new TextBlock { @@ -227,9 +201,7 @@ public QuickShellRunSettingsWindow( }; root.Children.Add(_statusText); - - - + var buttons = new StackPanel { Orientation = Orientation.Horizontal, @@ -261,9 +233,7 @@ public QuickShellRunSettingsWindow( buttons.Children.Add(save); buttons.Children.Add(done); root.Children.Add(buttons); - - - + Content = root; LoadCurrentValues(); @@ -271,9 +241,7 @@ public QuickShellRunSettingsWindow( _baseline = CaptureSnapshot(); } - - - + private void LoadCurrentValues() { @@ -291,9 +259,7 @@ private void LoadCurrentValues() _singleWindowTabsBox.IsChecked = !_settings.ReadSeparateWindowsForMultiLaunch(); } - - - + private void RestoreBaseline() { @@ -307,9 +273,7 @@ private void RestoreBaseline() _settings.SaveMultiLaunchPresentation(_baseline.SingleWindowTabs); } - - - + private SettingsSnapshot CaptureSnapshot() => new( @@ -323,9 +287,7 @@ private SettingsSnapshot CaptureSnapshot() => QuickShellRecentSettings.FromEnabled(_showRecentsBox.IsChecked == true), _singleWindowTabsBox.IsChecked == true); - - - + private void ReloadProfileChoices() { @@ -343,9 +305,7 @@ private void ReloadProfileChoices() _defaultProfileBox.Items.Add(new { choice.Id, choice.Label }); } - - - + _defaultProfileBox.SelectedValue = RunTerminalChoices.GetDefaultProfileChoices(_catalog, app) .Any(choice => choice.Id.Equals(selected, StringComparison.OrdinalIgnoreCase)) @@ -355,9 +315,7 @@ private void ReloadProfileChoices() : TerminalHostIds.DefaultProfile; } - - - + private bool HasUnsavedChanges() { var current = CaptureSnapshot(); @@ -391,9 +349,7 @@ private bool Save() return true; } - - - + private void ExportShortcuts() { @@ -407,9 +363,7 @@ private void ExportShortcuts() } } - - - + private void ImportShortcuts(bool replace) { @@ -425,13 +379,9 @@ private void ImportShortcuts(bool replace) } } - - - + private void SetStatus(string message) => _statusText.Text = message; - - - + private static TextBlock Heading(string text) => new() { @@ -443,9 +393,7 @@ private void ImportShortcuts(bool replace) Margin = new Thickness(0, 12, 0, 8), }; - - - + private static TextBlock Label(string text) => new() { @@ -455,9 +403,7 @@ private void ImportShortcuts(bool replace) Margin = new Thickness(0, 0, 0, 4), }; - - - + private static TextBlock Help(string text) => new() { @@ -473,9 +419,7 @@ private void ImportShortcuts(bool replace) FontSize = 12, }; - - - + private static ComboBox Combo(IReadOnlyList<(string Id, string Label)> choices) { @@ -499,15 +443,11 @@ private static ComboBox Combo(IReadOnlyList<(string Id, string Label)> choices) box.Items.Add(new { choice.Id, choice.Label }); } - - - + return box; } - - - + private static Button TooltipButton(string text, string tooltip, Action action) { @@ -533,9 +473,7 @@ private static Button TooltipButton(string text, string tooltip, Action action) return button; } - - - + private readonly record struct SettingsSnapshot( string TerminalApp, @@ -549,9 +487,7 @@ private readonly record struct SettingsSnapshot( bool SingleWindowTabs); } - - - + internal static class QuickShellRunSettingsDialog { @@ -573,9 +509,7 @@ void ShowWindow() window.ShowDialog(); } - - - + var app = Application.Current; if (app?.Dispatcher.CheckAccess() == true) diff --git a/QuickShell/Services/SectionListItems.cs b/QuickShell/Services/SectionListItems.cs index 2ba19ce2..af5075cf 100644 --- a/QuickShell/Services/SectionListItems.cs +++ b/QuickShell/Services/SectionListItems.cs @@ -1,8 +1,6 @@ using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; - namespace QuickShell.Services; - /// /// Emits CmdPal section headers per PowerToys PR #43952: a row /// (no command, non-empty section/title) renders the visible header; stamping @@ -17,15 +15,12 @@ public static IEnumerable InSection(string sectionTitle, IEnumerable< { return materialized; } - if (string.IsNullOrWhiteSpace(sectionTitle)) { return materialized; } - return PrependHeader(sectionTitle, materialized); } - public static IEnumerable PrependHeader(string sectionTitle, IReadOnlyList items) { yield return CreateHeader(sectionTitle); @@ -34,7 +29,6 @@ public static IEnumerable PrependHeader(string sectionTitle, IReadOnl yield return item; } } - public static Separator CreateHeader(string sectionTitle) => new(sectionTitle); } \ No newline at end of file