Add format and scope arguments to /listvar

b61344185c4d9a29793938daea7fbc54cb0b0d0d

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +80 -27Ignore whitespace
public/scripts/variables.js+80 -27
@@ -1,5 +1,6 @@
11import { chat_metadata, getCurrentChatId, saveSettingsDebounced, sendSystemMessage, system_message_types } from '../script.js';
22import { extension_settings, saveMetadataDebounced } from './extensions.js';
3+import { callGenericPopup, POPUP_TYPE } from './popup.js';
34import { executeSlashCommandsWithOptions } from './slash-commands.js';
45import { SlashCommand } from './slash-commands/SlashCommand.js';
56import { SlashCommandAbortController } from './slash-commands/SlashCommandAbortController.js';
@@ -303,24 +304,48 @@ export function replaceVariableMacros(input) {
303304 return lines.join('\n');
304305}
305306
306307async function listVariablesCallback(args) {
308+ const type = String(args?.format || '').toLowerCase().trim() || 'popup';
309+ const scope = String(args?.scope || '').toLowerCase().trim() || 'all';
307310 if (!chat_metadata.variables) {
308311 chat_metadata.variables = {};
309312 }
310313
311- const localVariables = Object.entries(chat_metadata.variables).map(([name, value]) => `${name}: ${value}`);
314+ const includeLocalVariables = scope === 'all' || scope === 'local';
312- const globalVariables = Object.entries(extension_settings.variables.global).map(([name, value]) => `${name}: ${value}`);
315+ const includeGlobalVariables = scope === 'all' || scope === 'global';
316+
317+ const localVariables = includeLocalVariables ? Object.entries(chat_metadata.variables).map(([name, value]) => `${name}: ${value}`) : [];
318+ const globalVariables = includeGlobalVariables ? Object.entries(extension_settings.variables.global).map(([name, value]) => `${name}: ${value}`) : [];
319+
320+ const jsonVariables = [
321+ ...Object.entries(chat_metadata.variables).map(x => ({ key: x[0], value: x[1], scope: 'local' })),
322+ ...Object.entries(extension_settings.variables.global).map(x => ({ key: x[0], value: x[1], scope: 'global' })),
323+ ];
313324
314325 const localVariablesString = localVariables.length > 0 ? localVariables.join('\n\n') : 'No local variables';
315326 const globalVariablesString = globalVariables.length > 0 ? globalVariables.join('\n\n') : 'No global variables';
316327 const chatName = getCurrentChatId();
317328
318329 const converter = new showdown.Converter();
319- const message = `### Local variables (${chatName}):\n${localVariablesString}\n\n### Global variables:\n${globalVariablesString}`;
330+ const message = [
331+ includeLocalVariables ? `### Local variables (${chatName}):\n${localVariablesString}` : '',
332+ includeGlobalVariables ? `### Global variables:\n${globalVariablesString}` : '',
333+ ].filter(x => x).join('\n\n');
320334 const htmlMessage = DOMPurify.sanitize(converter.makeHtml(message));
321335
322- sendSystemMessage(system_message_types.GENERIC, htmlMessage);
336+ switch (type) {
323- return '';
337+ case 'none':
338+ break;
339+ case 'chat':
340+ sendSystemMessage(system_message_types.GENERIC, htmlMessage);
341+ break;
342+ case 'popup':
343+ default:
344+ await callGenericPopup(htmlMessage, POPUP_TYPE.TEXT);
345+ break;
346+ }
347+
348+ return JSON.stringify(jsonVariables);
324349}
325350
326351/**
@@ -887,7 +912,35 @@ export function registerVariableCommands() {
887912 name: 'listvar',
888913 callback: listVariablesCallback,
889914 aliases: ['listchatvar'],
890- helpString: 'List registered chat variables.',
915+ helpString: 'List registered chat variables. Displays variables in a popup by default. Use the <code>format</code> argument to change the output format.',
916+ returns: 'JSON list of local variables',
917+ namedArgumentList: [
918+ SlashCommandNamedArgument.fromProps({
919+ name: 'scope',
920+ description: 'filter variables by scope',
921+ typeList: [ARGUMENT_TYPE.STRING],
922+ defaultValue: 'all',
923+ isRequired: false,
924+ forceEnum: true,
925+ enumList: [
926+ new SlashCommandEnumValue('all', 'All variables', enumTypes.enum, enumIcons.variable),
927+ new SlashCommandEnumValue('local', 'Local variables', enumTypes.enum, enumIcons.localVariable),
928+ new SlashCommandEnumValue('global', 'Global variables', enumTypes.enum, enumIcons.globalVariable),
929+ ],
930+ }),
931+ SlashCommandNamedArgument.fromProps({
932+ name: 'format',
933+ description: 'output format',
934+ typeList: [ARGUMENT_TYPE.STRING],
935+ isRequired: true,
936+ forceEnum: true,
937+ enumList: [
938+ new SlashCommandEnumValue('popup', 'Show variables in a popup.', enumTypes.enum, enumIcons.default),
939+ new SlashCommandEnumValue('chat', 'Post a system message to the chat.', enumTypes.enum, enumIcons.message),
940+ new SlashCommandEnumValue('none', 'Just return the variables as a JSON list.', enumTypes.enum, enumIcons.array),
941+ ],
942+ }),
943+ ],
891944 }));
892945 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
893946 name: 'setvar',
@@ -1276,16 +1329,16 @@ export function registerVariableCommands() {
12761329 }),
12771330 new SlashCommandNamedArgument(
12781331 'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
12791332 new SlashCommandEnumValue('gt', 'a > b'),
12801333 new SlashCommandEnumValue('gte', 'a >= b'),
12811334 new SlashCommandEnumValue('lt', 'a < b'),
12821335 new SlashCommandEnumValue('lte', 'a <= b'),
12831336 new SlashCommandEnumValue('eq', 'a == b'),
12841337 new SlashCommandEnumValue('neq', 'a !== b'),
12851338 new SlashCommandEnumValue('not', '!a'),
12861339 new SlashCommandEnumValue('in', 'a includes b'),
12871340 new SlashCommandEnumValue('nin', 'a not includes b'),
12881341 ],
12891342 ),
12901343 new SlashCommandNamedArgument(
12911344 'else', 'command to execute if not true', [ARGUMENT_TYPE.CLOSURE, ARGUMENT_TYPE.SUBCOMMAND], false,
@@ -1354,16 +1407,16 @@ export function registerVariableCommands() {
13541407 }),
13551408 new SlashCommandNamedArgument(
13561409 'rule', 'comparison rule', [ARGUMENT_TYPE.STRING], true, false, null, [
13571410 new SlashCommandEnumValue('gt', 'a > b'),
13581411 new SlashCommandEnumValue('gte', 'a >= b'),
13591412 new SlashCommandEnumValue('lt', 'a < b'),
13601413 new SlashCommandEnumValue('lte', 'a <= b'),
13611414 new SlashCommandEnumValue('eq', 'a == b'),
13621415 new SlashCommandEnumValue('neq', 'a !== b'),
13631416 new SlashCommandEnumValue('not', '!a'),
13641417 new SlashCommandEnumValue('in', 'a includes b'),
13651418 new SlashCommandEnumValue('nin', 'a not includes b'),
13661419 ],
13671420 ),
13681421 new SlashCommandNamedArgument(
13691422 'guard', 'disable loop iteration limit', [ARGUMENT_TYPE.STRING], false, false, null, commonEnumProviders.boolean('onOff')(),