Add SedEnhanced plugin (#1188)
* add SedEnchanced * [SedEnhanced] add README.md * [SedEnhanced] clarify in readme * [SedEnhanced] fix typo in readme * [SedEnhanced] make `sedRegex` const * [SedEnhanced] Apply strict checking suggestion Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * [SedEnhanced] remove `export` from `currentReply` Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * [SedEnhanced] fix dodgy patch regex * [SedEnhanced] improve patch regex further * [SedEnhanced] add license header * [SedEnhancer] add reasonable limits to patch `match` * [SedEnhancer] improve reply logic * [SedEnhanced] tighten patch further * [SedEnhanced] use \i for identifier * [SedEnhanced] add explanation for large pattern * [SedEnhanced] fix typescript errors * [SedEnhanced] fix remaining issues (hopefully) * remove stuff we dont care about because I hate myself * Update index.ts * Update index.ts * revert `[...flags]` back to `flags` --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
190da1d3c8
commit
cb00a5b2c0
2 changed files with 87 additions and 0 deletions
75
src/equicordplugins/sedEnhanced/index.ts
Normal file
75
src/equicordplugins/sedEnhanced/index.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2026 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { MessageActions, MessageStore, PendingReplyStore, UserStore } from "@webpack/common";
|
||||
|
||||
const sedRegex = /^s(?<sep>[/|$#@!])(?<match>(?!\1)(?:(?![^\\]\1).)*.|)\1(?<replace>(?!\1)(?:(?![^\\]\1).)*.|)\1?(?<modes>[rgmisudyv]*)$/;
|
||||
const settings = definePluginSettings({
|
||||
regexByDefault: {
|
||||
description: "Inverts the `r` flag, so using the `r` flag enables non-regex mode, and omitting it uses regex mode.",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "SedEnhanced",
|
||||
description: "Expands on Discord's rudimentary `sed` support.",
|
||||
authors: [EquicordDevs.dawn, EquicordDevs.Willow, EquicordDevs.kat],
|
||||
patches: [
|
||||
{
|
||||
find: ".SLASH_COMMAND_USED,{",
|
||||
replacement: {
|
||||
match: /searchReplace:\{match:(\i\(\)\.anyScopeRegex)/,
|
||||
replace: "searchReplace:{match:$1($self.sedRegex),action:$self.searchReplace},_eq_$&"
|
||||
}
|
||||
}
|
||||
],
|
||||
settings,
|
||||
sedRegex,
|
||||
searchReplace(content, { isEdit, channel }) {
|
||||
if (isEdit) return;
|
||||
|
||||
const pendingReply = PendingReplyStore.getPendingReply(channel.id)?.message;
|
||||
const toEdit = pendingReply ?? MessageStore.getLastEditableMessage(channel.id);
|
||||
if (pendingReply && pendingReply.author.id !== UserStore.getCurrentUser()?.id || toEdit?.id == null) return { content: "" };
|
||||
|
||||
const groups = content.match(sedRegex)?.groups;
|
||||
if (groups?.match == null || groups?.replace == null || groups?.modes == null) return;
|
||||
|
||||
let { match: pattern, replace, modes } = groups;
|
||||
const flags = modes.split("");
|
||||
const isRegex = flags.includes("r") !== settings.store.regexByDefault;
|
||||
|
||||
if (!isRegex) {
|
||||
const escapeChars = /\\([*?+/])/g;
|
||||
pattern = pattern.replace(escapeChars, (_, x) => x);
|
||||
replace = replace.replace(escapeChars, (_, x) => x);
|
||||
}
|
||||
|
||||
let find: string | RegExp = pattern;
|
||||
if (isRegex) {
|
||||
try {
|
||||
const regexFlags = flags.filter(f => "gmisudyv".includes(f)).join("");
|
||||
find = new RegExp(pattern, regexFlags);
|
||||
} catch {
|
||||
return { content: "" };
|
||||
}
|
||||
}
|
||||
|
||||
const replaced = flags.includes("g") ? toEdit.content.replaceAll(find, replace) : toEdit.content.replace(find, replace);
|
||||
if (!replaced.trim() && toEdit.attachments.length === 0) {
|
||||
MessageActions.deleteMessage(channel.id, toEdit.id);
|
||||
} else if (replaced !== toEdit.content) {
|
||||
MessageActions.editMessage(channel.id, toEdit.id, { content: replaced });
|
||||
}
|
||||
|
||||
return { content: "" };
|
||||
}
|
||||
});
|
||||
|
|
@ -1366,6 +1366,18 @@ export const EquicordDevs = Object.freeze({
|
|||
name: "jahsohsani",
|
||||
id: 806442568564604968n
|
||||
},
|
||||
dawn: {
|
||||
name: "dawn",
|
||||
id: 604653220341743618n
|
||||
},
|
||||
Willow: {
|
||||
name: "Willow",
|
||||
id: 965933914092888074n
|
||||
},
|
||||
kat: {
|
||||
name: "kat",
|
||||
id: 665120188047556609n
|
||||
},
|
||||
} satisfies Record<string, Dev>);
|
||||
|
||||
// iife so #__PURE__ works correctly
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue