Repository: oliverschwendener/ueli
Pull request #1256 (2024-11-23 10:13:38)

allow different results from multiple search engines

![image](https://github.com/user-attachments/assets/65f74a5e-7b63-4e31-b35f-99a378d3142a)


#1254


Patch:
diff --git a/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.ts b/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.ts
index 8329ed26..ce323a07 100644
--- a/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.ts
+++ b/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.ts
@@ -32,35 +32,36 @@ export class CustomWebSearchExtension implements Extension {
         return [];
     }
 
+    private createInstantSearchResultItem(engine: CustomSearchEngineSetting, searchTerm: string): SearchResultItem {
+        const searchInput = searchTerm.replace(engine.prefix, "").trim();
+        const encodeSearchInput = engine.encodeSearchTerm ? encodeURIComponent(searchInput) : searchInput;
+        const searchUrl = engine.url.replace("{{query}}", encodeSearchInput);
+        return {
+            name: engine.name,
+            description: `Search in ${engine.name}`,
+            id: `${engine.name}:instantResult`,
+            image: this.urlImageGenerator.getImage(new URL(searchUrl).origin),
+            defaultAction: {
+                handlerId: "Url",
+                description: `Search in default Browser`,
+                argument: searchUrl,
+            },
+        };
+    }
+
     public getInstantSearchResultItems(searchTerm: string): SearchResultItem[] {
         const customSearchEngines = this.settingsManager.getValue<CustomSearchEngineSetting[]>(
             getExtensionSettingKey(this.id, "customSearchEngines"),
             this.getSettingDefaultValue("customSearchEngines"),
         );
 
-        const selectedSearchEngine = customSearchEngines.find((engine) => searchTerm.startsWith(engine.prefix));
+        const selectedSearchEngines = customSearchEngines.filter((engine) => searchTerm.startsWith(engine.prefix));
 
-        if (!selectedSearchEngine) {
+        if (selectedSearchEngines.length === 0) {
             return [];
         }
 
-        const searchInput = searchTerm.replace(selectedSearchEngine.prefix, "").trim();
-        const encodeSearchInput = selectedSearchEngine.encodeSearchTerm ? encodeURIComponent(searchInput) : searchInput;
-        const searchUrl = selectedSearchEngine.url.replace("{{query}}", encodeSearchInput);
-
-        return [
-            {
-                name: selectedSearchEngine.name,
-                description: `Search in ${selectedSearchEngine.name}`,
-                id: `${selectedSearchEngine.name}:instantResult`,
-                image: this.urlImageGenerator.getImage(new URL(searchUrl).origin),
-                defaultAction: {
-                    handlerId: "Url",
-                    description: `Search in default Browser`,
-                    argument: searchUrl,
-                },
-            },
-        ];
+        return selectedSearchEngines.map((engine) => this.createInstantSearchResultItem(engine, searchTerm));
     }
 
     public isSupported(): boolean {


Test patch:
diff --git a/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.test.ts b/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.test.ts
index b0754131..6d44390f 100644
--- a/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.test.ts
+++ b/src/main/Extensions/CustomWebSearch/CustomWebSearchExtension.test.ts
@@ -28,6 +28,20 @@ const getSearchEngineSettings = (searchEngineNames: string[]): CustomSearchEngin
             prefix: "domain",
             url: "https://{{query}}.ueli.app/test",
         },
+        {
+            encodeSearchTerm: true,
+            id: "00000000-0000-0000-0000-000000000003",
+            name: "g",
+            prefix: "g",
+            url: "https://ueli.app/g/{{query}}",
+        },
+        {
+            encodeSearchTerm: true,
+            id: "00000000-0000-0000-0000-000000000004",
+            name: "genius",
+            prefix: "genius",
+            url: "https://ueli.app/genius/{{query}}",
+        },
     ];
     return customSearchEngines.filter((s) => searchEngineNames.includes(s.name));
 };
@@ -125,5 +139,20 @@ describe(CustomWebSearchExtension, () => {
             expect(results[0].defaultAction.handlerId).toEqual("Url");
             expect(results[0].defaultAction.argument).toEqual("https://testinput.ueli.app/test");
         });
+
+        it("should allow multiple search results, when multiple search engines match", () => {
+            const getValueMock = vi.fn().mockReturnValue(getSearchEngineSettings(["g", "genius"]));
+            const settingsManager = <SettingsManager>{
+                getValue: (k, d, s) => getValueMock(k, d, s),
+            };
+            const customWebSearch = new CustomWebSearchExtension(assetPathResolver, settingsManager, urlImageGenerator);
+
+            const results = customWebSearch.getInstantSearchResultItems("genius testinput");
+            expect(results).toHaveLength(2);
+            expect(results[0].defaultAction.handlerId).toEqual("Url");
+            expect(results[0].defaultAction.argument).toEqual("https://ueli.app/g/enius%20testinput");
+            expect(results[1].defaultAction.handlerId).toEqual("Url");
+            expect(results[1].defaultAction.argument).toEqual("https://ueli.app/genius/testinput");
+        });
     });
 });