SillyTavern/public/scripts/extensions/regex/index.js

375 lines
15 KiB
JavaScript
Raw Normal View History

2023-12-02 19:04:51 +01:00
import { callPopup, getCurrentChatId, reloadCurrentChat, saveSettingsDebounced } from '../../../script.js';
import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js';
STscript Parser Rewrite (#1965) * set isForced to true on input * make floating auto-complete follow horizontal scrolling * add callable closure vars * changes to /let and /var for callable closures * fix error message * fix scope for closure arguments * if should return the pipe result from closures * use /run to call closures and no arguments on immediate closures * throw exception from QRs window-function if no match * when to show autocomplete vs info only * autocomplete positioning * autocomplete styling * add theming to autocomplete (theme, dark, light) * improve autocomplete show/hide logic and editor selection * use blur tint color instead of chat tint color and use blur setting * cleanup and docs * use scope macros for QR args * add enter to select autocomplete * fix no executor found * cleanup and comment * fix alias list in help string * fallback to empty string piped value if null or undefined * fix typo * blur textarea on ctrl+enter execute (and refocus after) * stop executeSlashCommand if parser throws * move /let and /var callbacks into functions * switch textarea to monospace when value starts with slash * add double pipe a pipe breaker * fix /? slash * remove some logging * add "/:name" as shorthand for "/run name" after all * move shit around * fix error message * use testRunShorthandEnd * use parseQuotedValue and parseValue to determine name for "/:" QR labels and set names can include spaces * add some adjustments to make autocomplete work properly some hint in there about "/:" would still be nice * add autocomplete style selector * only strip quotes from subcommand if they are at both ends * fix JSDoc * escaping * allow open quotes on dry run * throwing shit at the wall for /: autocomplete * escapes only for symbols * clean up autocomplete * improve performance * fix scope macros * remove unescaping of pipes * fix macros in scope copy * fix "/? slash" * don't run parser for getNameAt if text has not changed * fix options filter * re-enable blur listener * restore selection on non-replace select * fix for escaping first character of value * add support for {{pipe}} and {{var::}} closures * add index support to var macro * add scoped var macro to macro help * more escape fixes * reduce autocomplete render debounce * cleanup * restore old escape handling and parser flag for strict escaping * fix "no match" autocomplete message * add dummy commands for comments and parser flag * fix type annotations * somewhat safer macro replacements * fix autocomplete select on blank / "no match" * fix cutting off handled part in substitution * add parser flag REPLACE_GETVAR Replaces all {{getvar::}} and {{getglobalvar::}} macros with {{var::}}. Inserts a series of command executors before the command with the macros that: - save {{pipe}} to a var - call /getvar or /getglobalvar to get the variable used in the macro - call /let to save the retrieved variable - return the saved {{pipe}} value This helps to avoid double-substitutions when the var values contain text that could be interpreted as macros. * remove old parser * fix send on enter when no match * deal with pipes in quoted values (loose escaping) * add default parser flags to user settings * allow quoted values in unnamed argument * set parser flag without explicit state to "on" * add click hint on parser error toast * dirty more detailed cmd defs * remove name from unnamed arg * move autocomplete into class and floating with details * replace jQuery's trigger('input') on #send_textarea with native events because jQuery does not dispatch the native event * fix ctrl+space * fix arrow navigation * add comments * fix pointer block * add static fromProps * fix up dummy commands * migrate all commands to addCommandObject * remove commented comment command * fix alias in details * add range as argument type * switch to addCommandObject * switch to addCommandObject * fix height * fix floating details position on left * re-enable blur event * use auto width for full details on floating autocomplete * auto-size floating full details * fix typo * re-enable blur listener * don't prevent enter when selected item is fully typed out * add autocomplete details tooltips * add language to slash command examples * move makeItem into option and command and fix click select * use autocomplete parts in /? slash * fix alias formatting * add language to slash command examples * fix details position on initial input history * small screen styles * replace registerSlashCommand with detailed declarations * put name on first line * add missing returns * fix missing comma * fix alias display in autocomplete list * remove args from help string * move parser settings to its own section * jsdoc * hljs stscript lang * add hljs to autocomplete help examples * add missing import * apply autocomplete colors to stscript codeblocks (hljs) * add fromProps * cache autocomplete elements * towards generic autocomplete * remove unused imports * fix blanks * add return types * re-enable blur * fix blank check * Caption messages by id * add aborting command execution * fix return type * fix chat input font reset * add slash command progress indicator * add missing return * mark registerSlashCommand deprecated * why?? * separate abort logic for commands * remove parsing of quoted values from unnamed arg * add adjustable autocomplete width * revert stop button pulse * add progress and pause/abort to QR editor * add resize event on autocomplete width change * add key= argument to all get vars * refactoring * introduce NamedArgumentAsignment * add TODOs * refactoring * record start and end of named arg assignment * refactoring * prevent duplicate calls to show * refactoring * remove macro ac * add secondary autocomplete and enum descriptions * add syntax highlighting to QR editor * add enum descriptions to /while * add /let key=... to scope variable names * add unnamed argument assignment class and unnamed argument splitting * fix QR editor style * remove dash before autocomplete help text * add autocomplete for unnamed enums * fix remaining dom after holding backslash * fix for unnamed enums * fix autocomplete for /parser-flag * add parser-flag enum help * fix type annotations * fix autocomplete result for /: * add colored autocomplete type icons * collapse second line autocomplete help if empty * mark optional named args in autocomplete * fix when what * remove duplicate debug buttons * dispatch input on autocomplete select * prevent grow from editor syntax layer * add auto-adjust qr editor caret color * remove text-shadow from autocomplete * join value strings in /let and /var * add /abort syntax highlight * fix attempting secondary result when there is none * rename settings headers and split autocomplete / stscript * add parser flag tooltips * add tooltips to chat width stops * fix typo * return clone of help item * fix enum string * don't make optional notice for autocomplete arguments smaller * avoid scrollbar in chat input * add rudimentary macro autocomplete * strip macro from helptext * finally remove closure delimiters around root * cleanup * fix index stuff for removed closure delimiters * fix type hint * add child commands to progress indicator * include sub-separator in macro autocomplete * remove all mentions of interruptsGeneration and purge * remove unused imports * fix syntax highlight with newline at end of input * cleanup select pointer events * coalesce onProgress call * add regex to STscript syntax highlighting * fix closure end * fix autocomplete type icon alignment * adjustments for small screens * fix removing wrong element * add missing "at=" arg to /sys, /comment, /sendas * add font scale setting for autocomplete * add target=_blank for parser flag links * fix for searching enums * remove REGEXP_MODE from hljs just causes trouble * fix autocomplete in closures * fix typo * fix type hint * Get rid of scroll bar on load * Add type hint for /send name argument. Fix 'at' types * Add 'negative' arg hint to /sd command * reenable blur event * Allow /summarize to process any text * Compact layout of script toggles * Expand CSS by default * fix double ranger indicator and adjust to narrow container * make custom css input fill available vertical space * reduce scroll lag * use default cursor on scrollbar * Clean-up module loading in index.html * fix tab indent with hljs --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-05-12 21:15:05 +02:00
import { SlashCommand } from '../../slash-commands/SlashCommand.js';
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
2024-02-10 20:57:22 +01:00
import { download, getFileText, getSortableDelay, uuidv4 } from '../../utils.js';
2023-12-02 19:04:51 +01:00
import { resolveVariable } from '../../variables.js';
import { regex_placement, runRegexScript } from './engine.js';
2023-07-20 19:32:15 +02:00
async function saveRegexScript(regexScript, existingScriptIndex) {
// If not editing
// Is the script name undefined or empty?
if (!regexScript.scriptName) {
2023-12-02 19:04:51 +01:00
toastr.error('Could not save regex script: The script name was undefined or empty!');
return;
}
if (existingScriptIndex === -1) {
2023-07-20 19:32:15 +02:00
// Does the script name already exist?
if (extension_settings.regex.find((e) => e.scriptName === regexScript.scriptName)) {
toastr.error(`Could not save regex script: A script with name ${regexScript.scriptName} already exists.`);
return;
}
} else {
// Does the script name already exist somewhere else?
// (If this fails, make it a .filter().map() to index array)
const foundIndex = extension_settings.regex.findIndex((e) => e.scriptName === regexScript.scriptName);
if (foundIndex !== existingScriptIndex && foundIndex !== -1) {
toastr.error(`Could not save regex script: A script with name ${regexScript.scriptName} already exists.`);
return;
}
}
// Is a find regex present?
if (regexScript.findRegex.length === 0) {
2023-12-02 19:04:51 +01:00
toastr.warning('This regex script will not work, but was saved anyway: A find regex isn\'t present.');
2023-07-20 19:32:15 +02:00
}
// Is there someplace to place results?
if (regexScript.placement.length === 0) {
2023-12-02 19:04:51 +01:00
toastr.warning('This regex script will not work, but was saved anyway: One "Affects" checkbox must be selected!');
2023-07-20 19:32:15 +02:00
}
if (existingScriptIndex !== -1) {
extension_settings.regex[existingScriptIndex] = regexScript;
} else {
extension_settings.regex.push(regexScript);
}
saveSettingsDebounced();
await loadRegexScripts();
// Reload the current chat to undo previous markdown
const currentChatId = getCurrentChatId();
if (currentChatId !== undefined && currentChatId !== null) {
await reloadCurrentChat();
}
}
async function deleteRegexScript({ existingId }) {
let scriptName = $(`#${existingId}`).find('.regex_script_name').text();
const existingScriptIndex = extension_settings.regex.findIndex((script) => script.scriptName === scriptName);
if (!existingScriptIndex || existingScriptIndex !== -1) {
extension_settings.regex.splice(existingScriptIndex, 1);
saveSettingsDebounced();
await loadRegexScripts();
}
}
async function loadRegexScripts() {
2023-12-02 19:04:51 +01:00
$('#saved_regex_scripts').empty();
2023-07-20 19:32:15 +02:00
const scriptTemplate = $(await renderExtensionTemplateAsync('regex', 'scriptTemplate'));
2023-07-20 19:32:15 +02:00
extension_settings.regex.forEach((script) => {
// Have to clone here
const scriptHtml = scriptTemplate.clone();
scriptHtml.attr('id', uuidv4());
scriptHtml.find('.regex_script_name').text(script.scriptName);
2023-12-02 19:04:51 +01:00
scriptHtml.find('.disable_regex').prop('checked', script.disabled ?? false)
2023-11-05 22:40:43 +01:00
.on('input', function () {
2023-12-02 19:04:51 +01:00
script.disabled = !!$(this).prop('checked');
reloadCurrentChat();
2023-11-05 22:40:43 +01:00
saveSettingsDebounced();
});
2023-11-05 22:40:43 +01:00
scriptHtml.find('.regex-toggle-on').on('click', function () {
2023-12-02 19:04:51 +01:00
scriptHtml.find('.disable_regex').prop('checked', true).trigger('input');
2023-11-05 22:40:43 +01:00
});
scriptHtml.find('.regex-toggle-off').on('click', function () {
2023-12-02 19:04:51 +01:00
scriptHtml.find('.disable_regex').prop('checked', false).trigger('input');
2023-11-05 22:40:43 +01:00
});
scriptHtml.find('.edit_existing_regex').on('click', async function () {
2023-12-02 19:04:51 +01:00
await onRegexEditorOpenClick(scriptHtml.attr('id'));
2023-07-20 19:32:15 +02:00
});
2024-02-10 20:57:22 +01:00
scriptHtml.find('.export_regex').on('click', async function () {
const fileName = `${script.scriptName.replace(/[\s.<>:"/\\|?*\x00-\x1F\x7F]/g, '_').toLowerCase()}.json`;
2024-02-10 20:57:22 +01:00
const fileData = JSON.stringify(script, null, 4);
download(fileData, fileName, 'application/json');
});
2023-11-05 22:40:43 +01:00
scriptHtml.find('.delete_regex').on('click', async function () {
2023-12-02 19:04:51 +01:00
const confirm = await callPopup('Are you sure you want to delete this regex script?', 'confirm');
2023-11-05 22:44:28 +01:00
if (!confirm) {
return;
}
2023-12-02 19:04:51 +01:00
await deleteRegexScript({ existingId: scriptHtml.attr('id') });
2023-07-20 19:32:15 +02:00
});
2023-12-02 19:04:51 +01:00
$('#saved_regex_scripts').append(scriptHtml);
2023-07-20 19:32:15 +02:00
});
}
async function onRegexEditorOpenClick(existingId) {
const editorHtml = $(await renderExtensionTemplateAsync('regex', 'editor'));
2023-07-20 19:32:15 +02:00
// If an ID exists, fill in all the values
let existingScriptIndex = -1;
if (existingId) {
const existingScriptName = $(`#${existingId}`).find('.regex_script_name').text();
existingScriptIndex = extension_settings.regex.findIndex((script) => script.scriptName === existingScriptName);
if (existingScriptIndex !== -1) {
const existingScript = extension_settings.regex[existingScriptIndex];
if (existingScript.scriptName) {
2023-12-02 19:04:51 +01:00
editorHtml.find('.regex_script_name').val(existingScript.scriptName);
2023-07-20 19:32:15 +02:00
} else {
2023-12-02 20:11:06 +01:00
toastr.error('This script doesn\'t have a name! Please delete it.');
2023-07-20 19:32:15 +02:00
return;
}
2023-12-02 19:04:51 +01:00
editorHtml.find('.find_regex').val(existingScript.findRegex || '');
editorHtml.find('.regex_replace_string').val(existingScript.replaceString || '');
editorHtml.find('.regex_trim_strings').val(existingScript.trimStrings?.join('\n') || []);
editorHtml.find('input[name="disabled"]').prop('checked', existingScript.disabled ?? false);
editorHtml.find('input[name="only_format_display"]').prop('checked', existingScript.markdownOnly ?? false);
editorHtml.find('input[name="only_format_prompt"]').prop('checked', existingScript.promptOnly ?? false);
editorHtml.find('input[name="run_on_edit"]').prop('checked', existingScript.runOnEdit ?? false);
editorHtml.find('input[name="substitute_regex"]').prop('checked', existingScript.substituteRegex ?? false);
editorHtml.find('input[name="min_depth"]').val(existingScript.minDepth ?? '');
editorHtml.find('input[name="max_depth"]').val(existingScript.maxDepth ?? '');
2023-07-20 19:32:15 +02:00
existingScript.placement.forEach((element) => {
editorHtml
.find(`input[name="replace_position"][value="${element}"]`)
2023-12-02 19:04:51 +01:00
.prop('checked', true);
2023-07-20 19:32:15 +02:00
});
}
} else {
editorHtml
2023-12-02 19:04:51 +01:00
.find('input[name="only_format_display"]')
.prop('checked', true);
2023-07-20 19:32:15 +02:00
editorHtml
2023-12-02 19:04:51 +01:00
.find('input[name="run_on_edit"]')
.prop('checked', true);
2023-07-20 19:32:15 +02:00
editorHtml
2023-12-02 19:04:51 +01:00
.find('input[name="replace_position"][value="1"]')
.prop('checked', true);
2023-07-20 19:32:15 +02:00
}
2024-01-04 03:34:38 +01:00
editorHtml.find('#regex_test_mode_toggle').on('click', function () {
editorHtml.find('#regex_test_mode').toggleClass('displayNone');
updateTestResult();
});
function updateTestResult() {
if (!editorHtml.find('#regex_test_mode').is(':visible')) {
return;
}
const testScript = {
scriptName: editorHtml.find('.regex_script_name').val(),
findRegex: editorHtml.find('.find_regex').val(),
replaceString: editorHtml.find('.regex_replace_string').val(),
trimStrings: String(editorHtml.find('.regex_trim_strings').val()).split('\n').filter((e) => e.length !== 0) || [],
substituteRegex: editorHtml.find('input[name="substitute_regex"]').prop('checked'),
};
const rawTestString = String(editorHtml.find('#regex_test_input').val());
const result = runRegexScript(testScript, rawTestString);
editorHtml.find('#regex_test_output').text(result);
}
editorHtml.find('input, textarea, select').on('input', updateTestResult);
2023-12-02 19:04:51 +01:00
const popupResult = await callPopup(editorHtml, 'confirm', undefined, { okButton: 'Save' });
2023-07-20 19:32:15 +02:00
if (popupResult) {
const newRegexScript = {
2023-12-02 19:04:51 +01:00
scriptName: editorHtml.find('.regex_script_name').val(),
findRegex: editorHtml.find('.find_regex').val(),
replaceString: editorHtml.find('.regex_replace_string').val(),
trimStrings: editorHtml.find('.regex_trim_strings').val().split('\n').filter((e) => e.length !== 0) || [],
2023-07-20 19:32:15 +02:00
placement:
editorHtml
2023-12-02 19:04:51 +01:00
.find('input[name="replace_position"]')
.filter(':checked')
2023-12-02 20:11:06 +01:00
.map(function () { return parseInt($(this).val()); })
2023-07-20 19:32:15 +02:00
.get()
2023-12-02 15:19:35 +01:00
.filter((e) => !isNaN(e)) || [],
disabled: editorHtml.find('input[name="disabled"]').prop('checked'),
markdownOnly: editorHtml.find('input[name="only_format_display"]').prop('checked'),
promptOnly: editorHtml.find('input[name="only_format_prompt"]').prop('checked'),
runOnEdit: editorHtml.find('input[name="run_on_edit"]').prop('checked'),
substituteRegex: editorHtml.find('input[name="substitute_regex"]').prop('checked'),
minDepth: parseInt(String(editorHtml.find('input[name="min_depth"]').val())),
maxDepth: parseInt(String(editorHtml.find('input[name="max_depth"]').val())),
2023-07-20 19:32:15 +02:00
};
saveRegexScript(newRegexScript, existingScriptIndex);
}
}
// Common settings migration function. Some parts will eventually be removed
// TODO: Maybe migrate placement to strings?
function migrateSettings() {
let performSave = false;
// Current: If MD Display is present in placement, remove it and add new placements/MD option
extension_settings.regex.forEach((script) => {
if (script.placement.includes(regex_placement.MD_DISPLAY)) {
script.placement = script.placement.length === 1 ?
Object.values(regex_placement).filter((e) => e !== regex_placement.MD_DISPLAY) :
script.placement = script.placement.filter((e) => e !== regex_placement.MD_DISPLAY);
2023-12-02 20:11:06 +01:00
script.markdownOnly = true;
script.promptOnly = true;
2023-07-20 19:32:15 +02:00
performSave = true;
}
// Old system and sendas placement migration
// 4 - sendAs
if (script.placement.includes(4)) {
script.placement = script.placement.length === 1 ?
[regex_placement.SLASH_COMMAND] :
script.placement = script.placement.filter((e) => e !== 4);
performSave = true;
}
});
if (performSave) {
saveSettingsDebounced();
}
}
2023-11-30 21:59:04 +01:00
/**
* /regex slash command callback
* @param {object} args Named arguments
* @param {string} value Unnamed argument
* @returns {string} The regexed string
*/
function runRegexCallback(args, value) {
if (!args.name) {
2023-12-02 19:04:51 +01:00
toastr.warning('No regex script name provided.');
2023-11-30 21:59:04 +01:00
return value;
}
const scriptName = String(resolveVariable(args.name));
for (const script of extension_settings.regex) {
if (String(script.scriptName).toLowerCase() === String(scriptName).toLowerCase()) {
if (script.disabled) {
toastr.warning(`Regex script "${scriptName}" is disabled.`);
return value;
}
console.debug(`Running regex callback for ${scriptName}`);
return runRegexScript(script, value);
}
}
toastr.warning(`Regex script "${scriptName}" not found.`);
return value;
}
2024-02-10 20:57:22 +01:00
/**
* Performs the import of the regex file.
* @param {File} file Input file
*/
async function onRegexImportFileChange(file) {
if (!file) {
toastr.error('No file provided.');
return;
}
try {
const fileText = await getFileText(file);
const regexScript = JSON.parse(fileText);
if (!regexScript.scriptName) {
throw new Error('No script name provided.');
}
extension_settings.regex.push(regexScript);
saveSettingsDebounced();
await loadRegexScripts();
toastr.success(`Regex script "${regexScript.scriptName}" imported.`);
} catch (error) {
console.log(error);
toastr.error('Invalid JSON file.');
return;
}
}
2023-07-20 19:32:15 +02:00
// Workaround for loading in sequence with other extensions
// NOTE: Always puts extension at the top of the list, but this is fine since it's static
jQuery(async () => {
if (extension_settings.regex) {
migrateSettings();
}
// Manually disable the extension since static imports auto-import the JS file
2023-12-02 19:04:51 +01:00
if (extension_settings.disabledExtensions.includes('regex')) {
2023-07-20 19:32:15 +02:00
return;
}
const settingsHtml = $(await renderExtensionTemplateAsync('regex', 'dropdown'));
2023-12-02 19:04:51 +01:00
$('#extensions_settings2').append(settingsHtml);
$('#open_regex_editor').on('click', function () {
2023-07-20 19:32:15 +02:00
onRegexEditorOpenClick(false);
2024-02-10 20:57:22 +01:00
});
$('#import_regex_file').on('change', async function () {
const inputElement = this instanceof HTMLInputElement && this;
await onRegexImportFileChange(inputElement.files[0]);
inputElement.value = '';
});
$('#import_regex').on('click', function () {
$('#import_regex_file').trigger('click');
2023-07-20 19:32:15 +02:00
});
$('#saved_regex_scripts').sortable({
delay: getSortableDelay(),
2023-07-20 19:32:15 +02:00
stop: function () {
let newScripts = [];
$('#saved_regex_scripts').children().each(function () {
2023-12-02 19:04:51 +01:00
const scriptName = $(this).find('.regex_script_name').text();
2023-07-20 19:32:15 +02:00
const existingScript = extension_settings.regex.find((e) => e.scriptName === scriptName);
if (existingScript) {
newScripts.push(existingScript);
}
});
extension_settings.regex = newScripts;
saveSettingsDebounced();
2023-12-02 19:04:51 +01:00
console.debug('Regex scripts reordered');
2023-07-20 19:32:15 +02:00
// TODO: Maybe reload regex scripts after move
},
});
await loadRegexScripts();
2023-12-02 19:04:51 +01:00
$('#saved_regex_scripts').sortable('enable');
2023-11-30 21:59:04 +01:00
STscript Parser Rewrite (#1965) * set isForced to true on input * make floating auto-complete follow horizontal scrolling * add callable closure vars * changes to /let and /var for callable closures * fix error message * fix scope for closure arguments * if should return the pipe result from closures * use /run to call closures and no arguments on immediate closures * throw exception from QRs window-function if no match * when to show autocomplete vs info only * autocomplete positioning * autocomplete styling * add theming to autocomplete (theme, dark, light) * improve autocomplete show/hide logic and editor selection * use blur tint color instead of chat tint color and use blur setting * cleanup and docs * use scope macros for QR args * add enter to select autocomplete * fix no executor found * cleanup and comment * fix alias list in help string * fallback to empty string piped value if null or undefined * fix typo * blur textarea on ctrl+enter execute (and refocus after) * stop executeSlashCommand if parser throws * move /let and /var callbacks into functions * switch textarea to monospace when value starts with slash * add double pipe a pipe breaker * fix /? slash * remove some logging * add "/:name" as shorthand for "/run name" after all * move shit around * fix error message * use testRunShorthandEnd * use parseQuotedValue and parseValue to determine name for "/:" QR labels and set names can include spaces * add some adjustments to make autocomplete work properly some hint in there about "/:" would still be nice * add autocomplete style selector * only strip quotes from subcommand if they are at both ends * fix JSDoc * escaping * allow open quotes on dry run * throwing shit at the wall for /: autocomplete * escapes only for symbols * clean up autocomplete * improve performance * fix scope macros * remove unescaping of pipes * fix macros in scope copy * fix "/? slash" * don't run parser for getNameAt if text has not changed * fix options filter * re-enable blur listener * restore selection on non-replace select * fix for escaping first character of value * add support for {{pipe}} and {{var::}} closures * add index support to var macro * add scoped var macro to macro help * more escape fixes * reduce autocomplete render debounce * cleanup * restore old escape handling and parser flag for strict escaping * fix "no match" autocomplete message * add dummy commands for comments and parser flag * fix type annotations * somewhat safer macro replacements * fix autocomplete select on blank / "no match" * fix cutting off handled part in substitution * add parser flag REPLACE_GETVAR Replaces all {{getvar::}} and {{getglobalvar::}} macros with {{var::}}. Inserts a series of command executors before the command with the macros that: - save {{pipe}} to a var - call /getvar or /getglobalvar to get the variable used in the macro - call /let to save the retrieved variable - return the saved {{pipe}} value This helps to avoid double-substitutions when the var values contain text that could be interpreted as macros. * remove old parser * fix send on enter when no match * deal with pipes in quoted values (loose escaping) * add default parser flags to user settings * allow quoted values in unnamed argument * set parser flag without explicit state to "on" * add click hint on parser error toast * dirty more detailed cmd defs * remove name from unnamed arg * move autocomplete into class and floating with details * replace jQuery's trigger('input') on #send_textarea with native events because jQuery does not dispatch the native event * fix ctrl+space * fix arrow navigation * add comments * fix pointer block * add static fromProps * fix up dummy commands * migrate all commands to addCommandObject * remove commented comment command * fix alias in details * add range as argument type * switch to addCommandObject * switch to addCommandObject * fix height * fix floating details position on left * re-enable blur event * use auto width for full details on floating autocomplete * auto-size floating full details * fix typo * re-enable blur listener * don't prevent enter when selected item is fully typed out * add autocomplete details tooltips * add language to slash command examples * move makeItem into option and command and fix click select * use autocomplete parts in /? slash * fix alias formatting * add language to slash command examples * fix details position on initial input history * small screen styles * replace registerSlashCommand with detailed declarations * put name on first line * add missing returns * fix missing comma * fix alias display in autocomplete list * remove args from help string * move parser settings to its own section * jsdoc * hljs stscript lang * add hljs to autocomplete help examples * add missing import * apply autocomplete colors to stscript codeblocks (hljs) * add fromProps * cache autocomplete elements * towards generic autocomplete * remove unused imports * fix blanks * add return types * re-enable blur * fix blank check * Caption messages by id * add aborting command execution * fix return type * fix chat input font reset * add slash command progress indicator * add missing return * mark registerSlashCommand deprecated * why?? * separate abort logic for commands * remove parsing of quoted values from unnamed arg * add adjustable autocomplete width * revert stop button pulse * add progress and pause/abort to QR editor * add resize event on autocomplete width change * add key= argument to all get vars * refactoring * introduce NamedArgumentAsignment * add TODOs * refactoring * record start and end of named arg assignment * refactoring * prevent duplicate calls to show * refactoring * remove macro ac * add secondary autocomplete and enum descriptions * add syntax highlighting to QR editor * add enum descriptions to /while * add /let key=... to scope variable names * add unnamed argument assignment class and unnamed argument splitting * fix QR editor style * remove dash before autocomplete help text * add autocomplete for unnamed enums * fix remaining dom after holding backslash * fix for unnamed enums * fix autocomplete for /parser-flag * add parser-flag enum help * fix type annotations * fix autocomplete result for /: * add colored autocomplete type icons * collapse second line autocomplete help if empty * mark optional named args in autocomplete * fix when what * remove duplicate debug buttons * dispatch input on autocomplete select * prevent grow from editor syntax layer * add auto-adjust qr editor caret color * remove text-shadow from autocomplete * join value strings in /let and /var * add /abort syntax highlight * fix attempting secondary result when there is none * rename settings headers and split autocomplete / stscript * add parser flag tooltips * add tooltips to chat width stops * fix typo * return clone of help item * fix enum string * don't make optional notice for autocomplete arguments smaller * avoid scrollbar in chat input * add rudimentary macro autocomplete * strip macro from helptext * finally remove closure delimiters around root * cleanup * fix index stuff for removed closure delimiters * fix type hint * add child commands to progress indicator * include sub-separator in macro autocomplete * remove all mentions of interruptsGeneration and purge * remove unused imports * fix syntax highlight with newline at end of input * cleanup select pointer events * coalesce onProgress call * add regex to STscript syntax highlighting * fix closure end * fix autocomplete type icon alignment * adjustments for small screens * fix removing wrong element * add missing "at=" arg to /sys, /comment, /sendas * add font scale setting for autocomplete * add target=_blank for parser flag links * fix for searching enums * remove REGEXP_MODE from hljs just causes trouble * fix autocomplete in closures * fix typo * fix type hint * Get rid of scroll bar on load * Add type hint for /send name argument. Fix 'at' types * Add 'negative' arg hint to /sd command * reenable blur event * Allow /summarize to process any text * Compact layout of script toggles * Expand CSS by default * fix double ranger indicator and adjust to narrow container * make custom css input fill available vertical space * reduce scroll lag * use default cursor on scrollbar * Clean-up module loading in index.html * fix tab indent with hljs --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2024-05-12 21:15:05 +02:00
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'regex',
callback: runRegexCallback,
returns: 'replaced text',
namedArgumentList: [
new SlashCommandNamedArgument(
'name', 'script name', [ARGUMENT_TYPE.STRING], true,
),
],
unnamedArgumentList: [
new SlashCommandArgument(
'input', [ARGUMENT_TYPE.STRING], false,
),
],
helpString: 'Runs a Regex extension script by name on the provided string. The script must be enabled.',
}));
2023-07-20 19:32:15 +02:00
});