mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
CmdPal: Add custom search engine option to Web Search extension (#43941)
## Summary of the Pull Request This PR allows user to customize a search query in Command Palette's Web Search built-in extension. This will also solve a problem with some browser that doesn't handle argument in form "? <query>" as it will allow user to specify the complete URI. - Introduces a new text box in Web Search extension settings for specifying a custom search engine URI - If the text box is non-empty, the provided URI is used for queries - If left empty, the extension defaults to previous behavior, sending queries in the format "? query" ## Pictures? Pictures! <img width="825" height="566" alt="image" src="https://github.com/user-attachments/assets/fbf3d3a5-ebfe-4c16-a5f1-0d044b6f9047" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #43940 - [x] Closes: #42867 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **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:
@@ -18,6 +18,8 @@ public class MockSettingsInterface : ISettingsInterface
|
||||
|
||||
public int HistoryItemCount { get; set; }
|
||||
|
||||
public string CustomSearchUri { get; }
|
||||
|
||||
public IReadOnlyList<HistoryItem> HistoryItems => _historyItems;
|
||||
|
||||
public MockSettingsInterface(int historyItemCount = 0, bool globalIfUri = true, List<HistoryItem> mockHistory = null)
|
||||
|
||||
@@ -28,12 +28,15 @@ internal sealed partial class SearchWebCommand : InvokableCommand
|
||||
|
||||
public override CommandResult Invoke()
|
||||
{
|
||||
if (!_browserInfoService.Open($"? {Arguments}"))
|
||||
var uri = BuildUri();
|
||||
|
||||
if (!_browserInfoService.Open(uri))
|
||||
{
|
||||
// TODO GH# 138 --> actually display feedback from the extension somewhere.
|
||||
return CommandResult.KeepOpen();
|
||||
}
|
||||
|
||||
// remember only the query, not the full URI
|
||||
if (_settingsManager.HistoryItemCount != 0)
|
||||
{
|
||||
_settingsManager.AddHistoryItem(new HistoryItem(Arguments, DateTime.Now));
|
||||
@@ -41,4 +44,28 @@ internal sealed partial class SearchWebCommand : InvokableCommand
|
||||
|
||||
return CommandResult.Dismiss();
|
||||
}
|
||||
|
||||
private string BuildUri()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_settingsManager.CustomSearchUri))
|
||||
{
|
||||
return $"? " + Arguments;
|
||||
}
|
||||
|
||||
// if the custom search URI contains query placeholder, replace it with the actual query
|
||||
// otherwise append the query to the end of the URI
|
||||
// support {query}, %query% or %s as placeholder
|
||||
var placeholderVariants = new[] { "{query}", "%query%", "%s" };
|
||||
foreach (var placeholder in placeholderVariants)
|
||||
{
|
||||
if (_settingsManager.CustomSearchUri.Contains(placeholder, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return _settingsManager.CustomSearchUri.Replace(placeholder, Uri.EscapeDataString(Arguments), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
// is this too smart?
|
||||
var separator = _settingsManager.CustomSearchUri.Contains('?') ? '&' : '?';
|
||||
return $"{_settingsManager.CustomSearchUri}{separator}q={Uri.EscapeDataString(Arguments)}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,5 +18,7 @@ public interface ISettingsInterface
|
||||
|
||||
public IReadOnlyList<HistoryItem> HistoryItems { get; }
|
||||
|
||||
string CustomSearchUri { get; }
|
||||
|
||||
public void AddHistoryItem(HistoryItem historyItem);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,15 @@ public class SettingsManager : JsonSettingsManager, ISettingsInterface
|
||||
Resources.plugin_global_if_uri,
|
||||
false);
|
||||
|
||||
private readonly TextSetting _customSearchUri = new(
|
||||
Namespaced(nameof(CustomSearchUri)),
|
||||
Resources.plugin_custom_search_uri,
|
||||
Resources.plugin_custom_search_uri,
|
||||
string.Empty)
|
||||
{
|
||||
Placeholder = Resources.plugin_custom_search_uri_placeholder,
|
||||
};
|
||||
|
||||
private readonly ChoiceSetSetting _historyItemCount = new(
|
||||
Namespaced(HistoryItemCountLegacySettingsKey),
|
||||
Resources.plugin_history_item_count,
|
||||
@@ -51,6 +60,8 @@ public class SettingsManager : JsonSettingsManager, ISettingsInterface
|
||||
|
||||
public int HistoryItemCount => int.TryParse(_historyItemCount.Value, out var value) && value >= 0 ? value : 0;
|
||||
|
||||
public string CustomSearchUri => _customSearchUri.Value ?? string.Empty;
|
||||
|
||||
public IReadOnlyList<HistoryItem> HistoryItems => _history.HistoryItems;
|
||||
|
||||
public SettingsManager()
|
||||
@@ -59,6 +70,7 @@ public class SettingsManager : JsonSettingsManager, ISettingsInterface
|
||||
|
||||
Settings.Add(_globalIfURI);
|
||||
Settings.Add(_historyItemCount);
|
||||
Settings.Add(_customSearchUri);
|
||||
|
||||
LoadSettings();
|
||||
|
||||
|
||||
@@ -159,6 +159,24 @@ namespace Microsoft.CmdPal.Ext.WebSearch.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Custom search engine URL.
|
||||
/// </summary>
|
||||
public static string plugin_custom_search_uri {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_custom_search_uri", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Use {query} or %s as the search query placeholder; e.g. https://www.bing.com/search?q={query}.
|
||||
/// </summary>
|
||||
public static string plugin_custom_search_uri_placeholder {
|
||||
get {
|
||||
return ResourceManager.GetString("plugin_custom_search_uri_placeholder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Searches the web with your default search engine.
|
||||
/// </summary>
|
||||
|
||||
@@ -187,4 +187,10 @@
|
||||
<data name="default_browser" xml:space="preserve">
|
||||
<value>default browser</value>
|
||||
</data>
|
||||
<data name="plugin_custom_search_uri" xml:space="preserve">
|
||||
<value>Custom search engine URL</value>
|
||||
</data>
|
||||
<data name="plugin_custom_search_uri_placeholder" xml:space="preserve">
|
||||
<value>Use {query} or %s as the search query placeholder; e.g. https://www.bing.com/search?q={query}</value>
|
||||
</data>
|
||||
</root>
|
||||
Reference in New Issue
Block a user