Merge pull request #3292 from SillyTavern/macrosparser

40d29bd4536565a041cc6514392ef416f0457b9b

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

Signed
2 files changed, +36 -1Ignore whitespace
public/scripts/macros.js+30 -1
@@ -26,6 +26,12 @@ Handlebars.registerHelper('helperMissing', function () {
26 * @typedef {(nonce: string) => string} MacroFunction26 * @typedef {(nonce: string) => string} MacroFunction
27 */27 */
2828
29/**
30 * @typedef {Object} CustomMacro
31 * @property {string} key - Macro name (key)
32 * @property {string} description - Optional description of the macro
33 */
34
29export class MacrosParser {35export class MacrosParser {
30 /**36 /**
31 * A map of registered macros.37 * A map of registered macros.
@@ -34,11 +40,28 @@ export class MacrosParser {
34 static #macros = new Map();40 static #macros = new Map();
3541
36 /**42 /**
43 * A map of macro descriptions.
44 * @type {Map<string, string>}
45 */
46 static #descriptions = new Map();
47
48 /**
49 * Returns an iterator over all registered macros.
50 * @returns {IterableIterator<CustomMacro>}
51 */
52 static [Symbol.iterator] = function* () {
53 for (const macro of MacrosParser.#macros.keys()) {
54 yield { key: macro, description: MacrosParser.#descriptions.get(macro) };
55 }
56 };
57
58 /**
37 * Registers a global macro that can be used anywhere where substitution is allowed.59 * Registers a global macro that can be used anywhere where substitution is allowed.
38 * @param {string} key Macro name (key)60 * @param {string} key Macro name (key)
39 * @param {string|MacroFunction} value A string or a function that returns a string61 * @param {string|MacroFunction} value A string or a function that returns a string
62 * @param {string} [description] Optional description of the macro
40 */63 */
41 static registerMacro(key, value) {64 static registerMacro(key, value, description = '') {
42 if (typeof key !== 'string') {65 if (typeof key !== 'string') {
43 throw new Error('Macro key must be a string');66 throw new Error('Macro key must be a string');
44 }67 }
@@ -64,6 +87,10 @@ export class MacrosParser {
64 }87 }
6588
66 this.#macros.set(key, value);89 this.#macros.set(key, value);
90
91 if (typeof description === 'string' && description) {
92 this.#descriptions.set(key, description);
93 }
67 }94 }
6895
69 /**96 /**
@@ -88,6 +115,8 @@ export class MacrosParser {
88 if (!deleted) {115 if (!deleted) {
89 console.warn(`Macro ${key} was not registered`);116 console.warn(`Macro ${key} was not registered`);
90 }117 }
118
119 this.#descriptions.delete(key);
91 }120 }
92121
93 /**122 /**
public/scripts/slash-commands/SlashCommandParser.js+6 -0
@@ -22,6 +22,8 @@ import { SlashCommandBreakPoint } from './SlashCommandBreakPoint.js';
22import { SlashCommandDebugController } from './SlashCommandDebugController.js';22import { SlashCommandDebugController } from './SlashCommandDebugController.js';
23import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js';23import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js';
24import { SlashCommandBreak } from './SlashCommandBreak.js';24import { SlashCommandBreak } from './SlashCommandBreak.js';
25import { MacrosParser } from '../macros.js';
26import { t } from '../i18n.js';
2527
26/** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */28/** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */
27/** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */29/** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */
@@ -494,6 +496,10 @@ export class SlashCommandParser {
494 li.querySelector('tt').textContent,496 li.querySelector('tt').textContent,
495 (li.querySelector('tt').remove(),li.innerHTML),497 (li.querySelector('tt').remove(),li.innerHTML),
496 ));498 ));
499 for (const macro of MacrosParser) {
500 if (options.find(it => it.name === macro.key)) continue;
501 options.push(new MacroAutoCompleteOption(macro.key, `{{${macro.key}}}`, macro.description || t`No description provided`));
502 }
497 const result = new AutoCompleteNameResult(503 const result = new AutoCompleteNameResult(
498 macro.name,504 macro.name,
499 macro.start + 2,505 macro.start + 2,