diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs index f1c6aa469525..c44874574399 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ListViewModel.cs @@ -52,6 +52,8 @@ public partial class ListViewModel : PageViewModel, IDisposable public string SearchText { get; private set; } = string.Empty; + public string InitialSearchText { get; private set; } = string.Empty; + public CommandItemViewModel EmptyContent { get; private set; } private bool _isDynamic; @@ -128,7 +130,7 @@ private void FetchItems() try { - IListItem[] newItems = _model.Unsafe!.GetItems(); + var newItems = _model.Unsafe!.GetItems(); // Collect all the items into new viewmodels Collection newViewModels = []; @@ -136,7 +138,7 @@ private void FetchItems() // TODO we can probably further optimize this by also keeping a // HashSet of every ExtensionObject we currently have, and only // building new viewmodels for the ones we haven't already built. - foreach (IListItem? item in newItems) + foreach (var item in newItems) { ListItemViewModel viewModel = new(item, new(this)); @@ -147,8 +149,8 @@ private void FetchItems() } } - IEnumerable firstTwenty = newViewModels.Take(20); - foreach (ListItemViewModel? item in firstTwenty) + var firstTwenty = newViewModels.Take(20); + foreach (var item in firstTwenty) { item?.SafeInitializeProperties(); } @@ -233,7 +235,7 @@ private void InitializeItemsTask(CancellationToken ct) iterable = Items.ToArray(); } - foreach (ListItemViewModel item in iterable) + foreach (var item in iterable) { ct.ThrowIfCancellationRequested(); @@ -266,8 +268,8 @@ private static int ScoreListItem(string query, CommandItemViewModel listItem) return 1; } - MatchResult nameMatch = StringMatcher.FuzzySearch(query, listItem.Title); - MatchResult descriptionMatch = StringMatcher.FuzzySearch(query, listItem.Subtitle); + var nameMatch = StringMatcher.FuzzySearch(query, listItem.Title); + var descriptionMatch = StringMatcher.FuzzySearch(query, listItem.Subtitle); return new[] { nameMatch.Score, (descriptionMatch.Score - 4) / 2, 0 }.Max(); } @@ -280,7 +282,7 @@ private struct ScoredListItemViewModel // Similarly stolen from ListHelpers.FilterList public static IEnumerable FilterList(IEnumerable items, string query) { - IOrderedEnumerable scores = items + var scores = items .Where(i => !i.IsInErrorState) .Select(li => new ScoredListItemViewModel() { ViewModel = li, Score = ScoreListItem(query, li) }) .Where(score => score.Score > 0) @@ -359,7 +361,7 @@ public override void InitializeProperties() { base.InitializeProperties(); - IListPage? model = _model.Unsafe; + var model = _model.Unsafe; if (model == null) { return; // throw? @@ -373,8 +375,9 @@ public override void InitializeProperties() _modelPlaceholderText = model.PlaceholderText; UpdateProperty(nameof(PlaceholderText)); - SearchText = model.SearchText; + InitialSearchText = SearchText = model.SearchText; UpdateProperty(nameof(SearchText)); + UpdateProperty(nameof(InitialSearchText)); EmptyContent = new(new(model.EmptyContent), PageContext); EmptyContent.SlowInitializeProperties(); @@ -385,7 +388,7 @@ public override void InitializeProperties() public void LoadMoreIfNeeded() { - IListPage? model = this._model.Unsafe; + var model = this._model.Unsafe; if (model == null) { return; @@ -412,7 +415,7 @@ protected override void FetchProperty(string propertyName) { base.FetchProperty(propertyName); - IListPage? model = this._model.Unsafe; + var model = this._model.Unsafe; if (model == null) { return; // throw? @@ -475,13 +478,13 @@ protected override void UnsafeCleanup() lock (_listLock) { - foreach (ListItemViewModel item in Items) + foreach (var item in Items) { item.SafeCleanup(); } Items.Clear(); - foreach (ListItemViewModel item in FilteredItems) + foreach (var item in FilteredItems) { item.SafeCleanup(); } @@ -489,7 +492,7 @@ protected override void UnsafeCleanup() FilteredItems.Clear(); } - IListPage? model = _model.Unsafe; + var model = _model.Unsafe; if (model != null) { model.ItemsChanged -= Model_ItemsChanged; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs index f41ac98ea3e0..c318f264c001 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml.cs @@ -250,18 +250,31 @@ private void FilterBox_TextChanged(object sender, TextChangedEventArgs e) private void Page_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { var property = e.PropertyName; - if (CurrentPageViewModel is ListViewModel list && - property == nameof(ListViewModel.SearchText)) + + if (CurrentPageViewModel is ListViewModel list) { - // Only if the text actually changed... - // (sometimes this triggers on a round-trip of the SearchText) - if (FilterBox.Text != list.SearchText) + if (property == nameof(ListViewModel.SearchText)) { - // ... Update our displayed text, and... - FilterBox.Text = list.SearchText; + // Only if the text actually changed... + // (sometimes this triggers on a round-trip of the SearchText) + if (FilterBox.Text != list.SearchText) + { + // ... Update our displayed text, and... + FilterBox.Text = list.SearchText; - // ... Move the cursor to the end of the input - FilterBox.Select(FilterBox.Text.Length, 0); + // ... Move the cursor to the end of the input + FilterBox.Select(FilterBox.Text.Length, 0); + } + } + else if (property == nameof(ListViewModel.InitialSearchText)) + { + // GH #38712: + // The ListPage will notify us of the `InitialSearchText` when + // we first load the viewmodel. We can use that as an + // opportunity to immediately select the search text. That lets + // the user start typing a new search without manually + // selecting the old one. + SelectSearch(); } } } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Properties/Resources.Designer.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Properties/Resources.Designer.cs index c20800d1c1b8..ce7119976303 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Properties/Resources.Designer.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowsServices/Properties/Resources.Designer.cs @@ -88,7 +88,7 @@ internal static string wox_plugin_service_name { } /// - /// Looks up a localized string similar to Open services (Ctrl+O). + /// Looks up a localized string similar to Open services. /// internal static string wox_plugin_service_open_services { get { @@ -133,7 +133,7 @@ internal static string wox_plugin_service_plugin_name { } /// - /// Looks up a localized string similar to Restart (Ctrl+R). + /// Looks up a localized string similar to Restart. /// internal static string wox_plugin_service_restart { get {