Add /regex-toggle slash command - Add /regex-toggle command, similarly to /extension-toggle - toggles the state of both global and character-bound scripts - Update jsdoc being inconsistent Closes #3613
| @@ -4,22 +4,16 @@ import { selected_group } from '../../group-chats.js'; | ||
| 4 | 4 | import { callGenericPopup, POPUP_TYPE } from '../../popup.js'; |
| 5 | 5 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; |
| 6 | 6 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; |
| 7 | 7 | import { commonEnumProviders, enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 8 | 8 | import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js'; |
| 9 | 9 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; |
| 10 | 10 | import { download, equalsIgnoreCaseAndAccents, getFileText, getSortableDelay, isFalseBoolean, isTrueBoolean, regexFromString, setInfoBlock, uuidv4 } from '../../utils.js'; |
| 11 | 11 | import { regex_placement, runRegexScript, substitute_find_regex } from './engine.js'; |
| 12 | 12 | import { t } from '../../i18n.js'; |
| 13 | 13 | import { accountStorage } from '../../util/AccountStorage.js'; |
| 14 | 14 | |
| 15 | 15 | /** |
| 16 | 16 | * @typedef {objectimport('../../char-data.js').RegexScriptData} RegexScript |
| 17 | - * @property {string} scriptName - The name of the script | |
| 18 | - * @property {boolean} disabled - Whether the script is disabled | |
| 19 | - * @property {string} replaceString - The replace string | |
| 20 | - * @property {string[]} trimStrings - The trim strings | |
| 21 | - * @property {string?} findRegex - The find regex | |
| 22 | - * @property {number?} substituteRegex - The substitute regex | |
| 23 | 17 | */ |
| 24 | 18 | |
| 25 | 19 | /** |
| @@ -418,6 +412,42 @@ function runRegexCallback(args, value) { | ||
| 418 | 412 | } |
| 419 | 413 | |
| 420 | 414 | /** |
| 415 | + * /regex-toggle slash command callback | |
| 416 | + * @param {{state: string}} args Named arguments | |
| 417 | + * @param {string} scriptName The name of the script to toggle | |
| 418 | + * @returns {Promise<string>} The regexed string | |
| 419 | + */ | |
| 420 | +async function toggleRegexCallback(args, scriptName) { | |
| 421 | + if (typeof scriptName !== 'string') throw new Error('Script name must be a string.'); | |
| 422 | + | |
| 423 | + const action = isTrueBoolean(args?.state) ? 'enable' : | |
| 424 | + isFalseBoolean(args?.state) ? 'disable' : | |
| 425 | + 'toggle'; | |
| 426 | + | |
| 427 | + const scripts = getRegexScripts(); | |
| 428 | + const script = scripts.find(s => equalsIgnoreCaseAndAccents(s.scriptName, scriptName)); | |
| 429 | + | |
| 430 | + if (!script) { | |
| 431 | + toastr.warning(t`Regex script '${scriptName}' not found.`); | |
| 432 | + return; | |
| 433 | + } | |
| 434 | + | |
| 435 | + script.disabled = action === 'enable' ? false : action === 'disable' ? true : !script.disabled; | |
| 436 | + | |
| 437 | + const isScoped = characters[this_chid]?.data?.extensions?.regex_scripts?.some(s => s.id === script.id); | |
| 438 | + const index = isScoped ? characters[this_chid]?.data?.extensions?.regex_scripts?.indexOf(script) : scripts.indexOf(script); | |
| 439 | + | |
| 440 | + await saveRegexScript(script, index, isScoped); | |
| 441 | + if (script.disabled) { | |
| 442 | + toastr.success(t`Regex script '${scriptName}' has been disabled.`); | |
| 443 | + } else { | |
| 444 | + toastr.success(t`Regex script '${scriptName}' has been enabled.`); | |
| 445 | + } | |
| 446 | + | |
| 447 | + return script.scriptName || ''; | |
| 448 | +} | |
| 449 | + | |
| 450 | +/** | |
| 421 | 451 | * Performs the import of the regex file. |
| 422 | 452 | * @param {File} file Input file |
| 423 | 453 | * @param {boolean} isScoped Is the script scoped to a character? |
| @@ -639,6 +669,43 @@ jQuery(async () => { | ||
| 639 | 669 | ], |
| 640 | 670 | helpString: 'Runs a Regex extension script by name on the provided string. The script must be enabled.', |
| 641 | 671 | })); |
| 672 | + SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | |
| 673 | + name: 'regex-toggle', | |
| 674 | + callback: toggleRegexCallback, | |
| 675 | + returns: 'The name of the script that was toggled', | |
| 676 | + namedArgumentList: [ | |
| 677 | + SlashCommandNamedArgument.fromProps({ | |
| 678 | + name: 'state', | |
| 679 | + description: 'Explicitly set the state of the script (true to enable, false to disable). If not provided, the state will be toggled to the opposite of the current state.', | |
| 680 | + typeList: [ARGUMENT_TYPE.BOOLEAN], | |
| 681 | + enumList: commonEnumProviders.boolean('trueFalse')(), | |
| 682 | + }), | |
| 683 | + ], | |
| 684 | + unnamedArgumentList: [ | |
| 685 | + SlashCommandArgument.fromProps({ | |
| 686 | + description: 'script name', | |
| 687 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 688 | + isRequired: true, | |
| 689 | + enumProvider: localEnumProviders.regexScripts, | |
| 690 | + }), | |
| 691 | + ], | |
| 692 | + helpString: ` | |
| 693 | + <div> | |
| 694 | + Toggles the state of a specified regex script. | |
| 695 | + </div> | |
| 696 | + <div> | |
| 697 | + <strong>Example:</strong> | |
| 698 | + <ul> | |
| 699 | + <li> | |
| 700 | + <pre><code class="language-stscript">/regex-toggle MyScript</code></pre> | |
| 701 | + </li> | |
| 702 | + <li> | |
| 703 | + <pre><code class="language-stscript">/regex-toggle state=off Character-specific Script</code></pre> | |
| 704 | + </li> | |
| 705 | + </ul> | |
| 706 | + </div> | |
| 707 | + `, | |
| 708 | + })); | |
| 642 | 709 | |
| 643 | 710 | eventSource.on(event_types.CHAT_CHANGED, checkEmbeddedRegexScripts); |
| 644 | 711 | eventSource.on(event_types.CHARACTER_DELETED, purgeEmbeddedRegexScripts); |