Plugin
ReplaceGoogleSearch
Replaces the Google search with different Engine(s)
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";8
import { definePluginSettings } from "@api/Settings";9
import { Flex } from "@components/Flex";10
import { Devs } from "@utils/constants";11
import definePlugin, { OptionType } from "@utils/types";12
import { Menu } from "@webpack/common";13
14
const DefaultEngines = {15
Google: "https:class="ts-cmt">//www.google.com/search?q=",16
DuckDuckGo: "https:class="ts-cmt">//duckduckgo.com/?q=",17
Brave: "https:class="ts-cmt">//search.brave.com/search?q=",18
Bing: "https:class="ts-cmt">//www.bing.com/search?q=",19
Yahoo: "https:class="ts-cmt">//search.yahoo.com/search?p=",20
Yandex: "https:class="ts-cmt">//yandex.com/search/?text=",21
GitHub: "https:class="ts-cmt">//github.com/search?q=",22
Reddit: "https:class="ts-cmt">//www.reddit.com/search?q=",23
Wikipedia: "https:class="ts-cmt">//wikipedia.org/w/index.php?search=",24
Startpage: "https:class="ts-cmt">//www.startpage.com/sp/search?query="25
} as const;26
27
const enum ReplacementEngineValue {28
OFF = "off",29
CUSTOM = "custom",30
}31
32
const settings = definePluginSettings({33
customEngineName: {34
description: "Name of the custom search engine",35
type: OptionType.STRING,36
placeholder: "Google"37
},38
customEngineURL: {39
displayName: "Custom Engine URL",40
description: "The URL of your Engine",41
type: OptionType.STRING,42
placeholder: "https:class="ts-cmt">//google.com/search?q="43
},44
replacementEngine: {45
description: "Replace with a specific search engine instead of adding a menu",46
type: OptionType.SELECT,47
options: [48
{ label: "Off", value: ReplacementEngineValue.OFF, default: true },49
{ label: "Custom Engine", value: ReplacementEngineValue.CUSTOM },50
...Object.keys(DefaultEngines).map(engine => ({ label: engine, value: engine }))51
]52
}53
});54
55
function search(src: string, engine: string) {56
open(engine + encodeURIComponent(src.trim()), "_blank");57
}58
59
function makeSearchItem(src: string) {60
const { customEngineName, customEngineURL, replacementEngine } = settings.store;61
62
const hasCustomEngine = Boolean(customEngineName && customEngineURL);63
const hasValidReplacementEngine = replacementEngine !== ReplacementEngineValue.OFF && !(replacementEngine === ReplacementEngineValue.CUSTOM && !hasCustomEngine);64
65
const Engines = { ...DefaultEngines };66
67
if (hasCustomEngine) {68
Engines[customEngineName!] = customEngineURL;69
}70
71
if (hasValidReplacementEngine) {72
const name = replacementEngine === ReplacementEngineValue.CUSTOM && hasCustomEngine73
? customEngineName74
: replacementEngine;75
76
return (77
<Menu.MenuItem78
label={`Search with ${name}`}79
key="search-custom-engine"80
id="vc-search-custom-engine"81
action={() => search(src, Engines[name!])}82
/>83
);84
}85
86
return (87
<Menu.MenuItem88
label="Search Text"89
key="search-text"90
id="vc-search-text"91
>92
{Object.keys(Engines).map(engine => {93
const key = "vc-search-content-" + engine;94
return (95
<Menu.MenuItem96
key={key}97
id={key}98
label={99
<Flex gap="0.5em" alignItems="center">100
<img101
style={{102
borderRadius: "50%"103
}}104
aria-hidden="true"105
height={16}106
width={16}107
src={`https:class="ts-cmt">//icons.duckduckgo.com/ip3/${new URL(Engines[engine]).hostname}.ico`}108
/>109
{engine}110
</Flex>111
}112
action={() => search(src, Engines[engine])}113
/>114
);115
})}116
</Menu.MenuItem>117
);118
}119
120
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, _props) => {121
const selection = document.getSelection()?.toString();122
if (!selection) return;123
124
const group = findGroupChildrenByChildId("search-google", children);125
if (group) {126
const idx = group.findIndex(c => c?.props?.id === "search-google");127
if (idx !== -1) group[idx] = makeSearchItem(selection);128
}129
};130
131
export default definePlugin({132
name: "ReplaceGoogleSearch",133
description: "Replaces the Google search with different Engine(s)",134
tags: ["Utility", "Customisation"],135
authors: [Devs.Moxxie, Devs.Ethan],136
137
settings,138
139
contextMenus: {140
"message": messageContextMenuPatch141
}142
});143