CmdPal: Add actionable hint to empty results in File Search extension (#41982)

## Summary of the Pull Request

This PR improves the user experience when no indexed files match the
query in the File Search extension.

- Show a hint on the empty results page when no indexed files are found.
- Provide fallback actions:
- Search entire PC – opens new File Explorer window with the query
searched in This PC.
- Open Windows Search settings – navigates to Windows Search settings to
review indexed locations.

<img width="1719" height="1072" alt="image"
src="https://github.com/user-attachments/assets/51bd7b4a-563f-4339-b179-8125c057b0af"
/>


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Related to: #38509
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
This commit is contained in:
Jiří Polášek
2025-09-24 20:01:03 +02:00
committed by GitHub
parent 314a6e73eb
commit 3f87a0c408
3 changed files with 79 additions and 12 deletions

View File

@@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
@@ -23,6 +25,9 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
private bool _isEmptyQuery = true;
private CommandItem _noSearchEmptyContent;
private CommandItem _nothingFoundEmptyContent;
public IndexerPage()
{
Id = "com.microsoft.indexer.fileSearch";
@@ -31,6 +36,7 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
PlaceholderText = Resources.Indexer_PlaceholderText;
_searchEngine = new();
_queryCookie = 10;
CreateEmptyContent();
}
public IndexerPage(string query, SearchEngine searchEngine, uint queryCookie, IList<IListItem> firstPageData)
@@ -43,9 +49,42 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
initialQuery = query;
SearchText = query;
disposeSearchEngine = false;
CreateEmptyContent();
}
public override ICommandItem EmptyContent => GetEmptyContent();
private void CreateEmptyContent()
{
_noSearchEmptyContent = new CommandItem(new NoOpCommand())
{
Icon = Icon,
Title = Resources.Indexer_Subtitle,
Subtitle = Resources.Indexer_NoSearchQueryMessageTip,
};
_nothingFoundEmptyContent = new CommandItem(new AnonymousCommand(StartManualSearch) { Name = Resources.Indexer_Command_SearchAllFiles! })
{
Icon = Icon,
Title = Resources.Indexer_NoResultsMessage,
Subtitle = Resources.Indexer_NoResultsMessageTip,
MoreCommands = [
new CommandContextItem(new OpenUrlCommand("ms-settings:search") { Name = Resources.Indexer_Command_OpenIndexerSettings! })
{
Title = Resources.Indexer_Command_SearchAllFiles!,
},
],
};
}
private void StartManualSearch()
{
// {20D04FE0-3AEA-1069-A2D8-08002B30309D} is CLSID for "This PC"
const string template = "search-ms:query={0}&crumb=location:::{{20D04FE0-3AEA-1069-A2D8-08002B30309D}}";
var encodedSearchText = UrlEncoder.Default.Encode(SearchText);
var command = string.Format(CultureInfo.CurrentCulture, template, encodedSearchText);
ShellHelpers.OpenInShell(command);
}
public override ICommandItem EmptyContent => _isEmptyQuery ? _noSearchEmptyContent : _nothingFoundEmptyContent;
public override void UpdateSearchText(string oldSearch, string newSearch)
{
@@ -74,16 +113,6 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
RaiseItemsChanged(_indexerListItems.Count);
}
private CommandItem GetEmptyContent()
{
return new CommandItem(new NoOpCommand())
{
Icon = Icon,
Title = _isEmptyQuery ? Resources.Indexer_Subtitle : Resources.Indexer_NoResultsMessage,
Subtitle = Resources.Indexer_NoResultsMessageTip,
};
}
private void Query(string query)
{
++_queryCookie;

View File

@@ -96,6 +96,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Open Windows Search settings.
/// </summary>
internal static string Indexer_Command_OpenIndexerSettings {
get {
return ResourceManager.GetString("Indexer_Command_OpenIndexerSettings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open path in console.
/// </summary>
@@ -123,6 +132,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Search all files.
/// </summary>
internal static string Indexer_Command_SearchAllFiles {
get {
return ResourceManager.GetString("Indexer_Command_SearchAllFiles", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show in folder.
/// </summary>
@@ -187,7 +205,8 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
/// <summary>
/// Looks up a localized string similar to Tip: Improve your search result using filters like in Windows Explorer. (For example: type:directory).
/// Looks up a localized string similar to Nothing was found in the indexed locations.
///You can try searching all files on this PC or adjust your indexing settings..
/// </summary>
internal static string Indexer_NoResultsMessageTip {
get {
@@ -195,6 +214,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory)..
/// </summary>
internal static string Indexer_NoSearchQueryMessageTip {
get {
return ResourceManager.GetString("Indexer_NoSearchQueryMessageTip", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search for files and folders....
/// </summary>

View File

@@ -184,6 +184,16 @@
<value>No items found</value>
</data>
<data name="Indexer_NoResultsMessageTip" xml:space="preserve">
<value>Nothing was found in the indexed locations.
You can try searching all files on this PC or adjust your indexing settings.</value>
</data>
<data name="Indexer_NoSearchQueryMessageTip" xml:space="preserve">
<value>Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory).</value>
</data>
<data name="Indexer_Command_OpenIndexerSettings" xml:space="preserve">
<value>Open Windows Search settings</value>
</data>
<data name="Indexer_Command_SearchAllFiles" xml:space="preserve">
<value>Search all files</value>
</data>
</root>