mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Parser followup (#2377)
* set pipe to empty string on empty closure * fix missing parser flags and scope * add closure serializing * add enum provider function to slash command arguments * add enum providers for /bg, /ask, and /go * fix index out of bounds returning undefined * keep whitespace as is in mixed unnamed args (string+closure) * add _hasUnnamedArgument to named arguments dictionary * allow /var key=x retrieval * add enum provider to /tag-add * fix typo (case) * add option to make enum matching optional * add executor to enum provider * change /tag-add enum provider to only show tags not already assigned * add enum provider to /tag-remove * fix name enum provider excluding groups * remove void from slash command callback return types * Lint undefined and null pipes * enable pointer events in chat autocomplete * fix type hint --------- Co-authored-by: LenAnderson <Anderson.Len@outlook.com> Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
@ -795,7 +795,7 @@ function letCallback(args, value) {
|
||||
|
||||
/**
|
||||
* Set or retrieve a variable in the current scope or nearest ancestor scope.
|
||||
* @param {{_scope:SlashCommandScope, key?:string, index?:string|number}} args Named arguments.
|
||||
* @param {{_hasUnnamedArgument:boolean, _scope:SlashCommandScope, key?:string, index?:string|number}} args Named arguments.
|
||||
* @param {string|SlashCommandClosure|(string|SlashCommandClosure)[]} value Name and optional value for the variable.
|
||||
* @returns The variable's value
|
||||
*/
|
||||
@ -803,9 +803,13 @@ function varCallback(args, value) {
|
||||
if (!Array.isArray(value)) value = [value];
|
||||
if (args.key !== undefined) {
|
||||
const key = args.key;
|
||||
const val = value.join(' ');
|
||||
args._scope.setVariable(key, val, args.index);
|
||||
return val;
|
||||
if (args._hasUnnamedArgument) {
|
||||
const val = value.join(' ');
|
||||
args._scope.setVariable(key, val, args.index);
|
||||
return val;
|
||||
} else {
|
||||
return args._scope.getVariable(key, args.index);
|
||||
}
|
||||
}
|
||||
const key = value.shift();
|
||||
if (value.length > 0) {
|
||||
@ -817,6 +821,30 @@ function varCallback(args, value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./slash-commands/SlashCommand.js').NamedArguments} args
|
||||
* @param {SlashCommandClosure} value
|
||||
* @returns {string}
|
||||
*/
|
||||
function closureSerializeCallback(args, value) {
|
||||
if (!(value instanceof SlashCommandClosure)) {
|
||||
throw new Error('unnamed argument must be a closure');
|
||||
}
|
||||
return value.rawText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./slash-commands/SlashCommand.js').NamedArguments} args
|
||||
* @param {import('./slash-commands/SlashCommand.js').UnnamedArguments} value
|
||||
* @returns {SlashCommandClosure}
|
||||
*/
|
||||
function closureDeserializeCallback(args, value) {
|
||||
const parser = new SlashCommandParser();
|
||||
const closure = parser.parse(value, true, args._parserFlags, args._abortController);
|
||||
closure.scope.parent = args._scope;
|
||||
return closure;
|
||||
}
|
||||
|
||||
export function registerVariableCommands() {
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'listvar',
|
||||
callback: listVariablesCallback,
|
||||
@ -1811,4 +1839,61 @@ export function registerVariableCommands() {
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'closure-serialize',
|
||||
/**
|
||||
*
|
||||
* @param {import('./slash-commands/SlashCommand.js').NamedArguments} args
|
||||
* @param {SlashCommandClosure} value
|
||||
* @returns {string}
|
||||
*/
|
||||
callback: (args, value)=>closureSerializeCallback(args, value),
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({ description: 'the closure to serialize',
|
||||
typeList: [ARGUMENT_TYPE.CLOSURE],
|
||||
isRequired: true,
|
||||
}),
|
||||
],
|
||||
returns: 'serialized closure as string',
|
||||
helpString: `
|
||||
<div>
|
||||
Serialize a closure as text that can be stored in global and chat variables.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Examples:</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<pre><code class="language-stscript">/closure-serialize {: x=1 /echo x is {{var::x}} and y is {{var::y}} :} |\n/setvar key=myClosure</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'closure-deserialize',
|
||||
/**
|
||||
* @param {import('./slash-commands/SlashCommand.js').NamedArguments} args
|
||||
* @param {import('./slash-commands/SlashCommand.js').UnnamedArguments} value
|
||||
* @returns {SlashCommandClosure}
|
||||
*/
|
||||
callback: (args, value)=>closureDeserializeCallback(args, value),
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({ description: 'serialized closure',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
}),
|
||||
],
|
||||
returns: 'deserialized closure',
|
||||
helpString: `
|
||||
<div>
|
||||
Deserialize a closure from text.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Examples:</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<pre><code class="language-stscript">/closure-deserialize {{getvar::myClosure}} |\n/let myClosure {{pipe}} |\n/let y bar |\n/:myClosure x=foo</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
}));
|
||||
}
|
||||
|
Reference in New Issue
Block a user