diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs index a51db9165d..1e5f0533c7 100644 --- a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs @@ -18,6 +18,8 @@ public class MockSettingsInterface : ISettingsInterface public int HistoryItemCount { get; set; } + public string CustomSearchUri { get; } + public IReadOnlyList HistoryItems => _historyItems; public MockSettingsInterface(int historyItemCount = 0, bool globalIfUri = true, List mockHistory = null) diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs index 98921aa8ae..1f5fdb8598 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs @@ -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)}"; + } } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs index cbbb86bbd2..cff6f8919d 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs @@ -18,5 +18,7 @@ public interface ISettingsInterface public IReadOnlyList HistoryItems { get; } + string CustomSearchUri { get; } + public void AddHistoryItem(HistoryItem historyItem); } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs index 8cc7734368..0af19e14c2 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs @@ -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 HistoryItems => _history.HistoryItems; public SettingsManager() @@ -59,6 +70,7 @@ public class SettingsManager : JsonSettingsManager, ISettingsInterface Settings.Add(_globalIfURI); Settings.Add(_historyItemCount); + Settings.Add(_customSearchUri); LoadSettings(); diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.Designer.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.Designer.cs index 090b54375d..9db0a40cac 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.Designer.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.Designer.cs @@ -159,6 +159,24 @@ namespace Microsoft.CmdPal.Ext.WebSearch.Properties { } } + /// + /// Looks up a localized string similar to Custom search engine URL. + /// + public static string plugin_custom_search_uri { + get { + return ResourceManager.GetString("plugin_custom_search_uri", resourceCulture); + } + } + + /// + /// 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}. + /// + public static string plugin_custom_search_uri_placeholder { + get { + return ResourceManager.GetString("plugin_custom_search_uri_placeholder", resourceCulture); + } + } + /// /// Looks up a localized string similar to Searches the web with your default search engine. /// diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.resx b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.resx index 032f89e7a5..c7f424c6f9 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.resx +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/Resources.resx @@ -187,4 +187,10 @@ default browser + + Custom search engine URL + + + Use {query} or %s as the search query placeholder; e.g. https://www.bing.com/search?q={query} + \ No newline at end of file