From 1dccb08cd66bd3f212c04c7509a031beca826ab2 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:04:36 +0200 Subject: [PATCH 1/2] Add enumerator for MacrosParser --- public/scripts/macros.js | 31 ++++++++++++++++++- .../slash-commands/SlashCommandParser.js | 4 +++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/public/scripts/macros.js b/public/scripts/macros.js index 3464b7a64..960dad146 100644 --- a/public/scripts/macros.js +++ b/public/scripts/macros.js @@ -26,6 +26,12 @@ Handlebars.registerHelper('helperMissing', function () { * @typedef {(nonce: string) => string} MacroFunction */ +/** + * @typedef {Object} CustomMacro + * @property {string} key - Macro name (key) + * @property {string} description - Optional description of the macro + */ + export class MacrosParser { /** * A map of registered macros. @@ -33,12 +39,29 @@ export class MacrosParser { */ static #macros = new Map(); + /** + * A map of macro descriptions. + * @type {Map} + */ + static #descriptions = new Map(); + + /** + * Returns an iterator over all registered macros. + * @returns {IterableIterator} + */ + static [Symbol.iterator] = function* () { + for (const macro of this.#macros.values()) { + yield { key: macro, description: this.#descriptions.get(macro) }; + } + }; + /** * Registers a global macro that can be used anywhere where substitution is allowed. * @param {string} key Macro name (key) * @param {string|MacroFunction} value A string or a function that returns a string + * @param {string} [description] Optional description of the macro */ - static registerMacro(key, value) { + static registerMacro(key, value, description = '') { if (typeof key !== 'string') { throw new Error('Macro key must be a string'); } @@ -64,6 +87,10 @@ export class MacrosParser { } this.#macros.set(key, value); + + if (typeof description === 'string' && description) { + this.#descriptions.set(key, description); + } } /** @@ -88,6 +115,8 @@ export class MacrosParser { if (!deleted) { console.warn(`Macro ${key} was not registered`); } + + this.#descriptions.delete(key); } /** diff --git a/public/scripts/slash-commands/SlashCommandParser.js b/public/scripts/slash-commands/SlashCommandParser.js index 539757568..aeda79d5a 100644 --- a/public/scripts/slash-commands/SlashCommandParser.js +++ b/public/scripts/slash-commands/SlashCommandParser.js @@ -22,6 +22,7 @@ import { SlashCommandBreakPoint } from './SlashCommandBreakPoint.js'; import { SlashCommandDebugController } from './SlashCommandDebugController.js'; import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js'; import { SlashCommandBreak } from './SlashCommandBreak.js'; +import { MacrosParser } from '../macros.js'; /** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */ /** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */ @@ -494,6 +495,9 @@ export class SlashCommandParser { li.querySelector('tt').textContent, (li.querySelector('tt').remove(),li.innerHTML), )); + for (const macro of MacrosParser) { + options.push(new MacroAutoCompleteOption(macro.name, `{{${macro.name}}}`, macro.description || 'No description provided')); + } const result = new AutoCompleteNameResult( macro.name, macro.start + 2, From 1f66bc775653664535355a4d4cf22884d292f3de Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 11 Jan 2025 23:18:03 +0200 Subject: [PATCH 2/2] Don't allow duplicate registrations --- public/scripts/macros.js | 4 ++-- public/scripts/slash-commands/SlashCommandParser.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/public/scripts/macros.js b/public/scripts/macros.js index 960dad146..64f0b4647 100644 --- a/public/scripts/macros.js +++ b/public/scripts/macros.js @@ -50,8 +50,8 @@ export class MacrosParser { * @returns {IterableIterator} */ static [Symbol.iterator] = function* () { - for (const macro of this.#macros.values()) { - yield { key: macro, description: this.#descriptions.get(macro) }; + for (const macro of MacrosParser.#macros.keys()) { + yield { key: macro, description: MacrosParser.#descriptions.get(macro) }; } }; diff --git a/public/scripts/slash-commands/SlashCommandParser.js b/public/scripts/slash-commands/SlashCommandParser.js index aeda79d5a..7f463d684 100644 --- a/public/scripts/slash-commands/SlashCommandParser.js +++ b/public/scripts/slash-commands/SlashCommandParser.js @@ -23,6 +23,7 @@ import { SlashCommandDebugController } from './SlashCommandDebugController.js'; import { commonEnumProviders } from './SlashCommandCommonEnumsProvider.js'; import { SlashCommandBreak } from './SlashCommandBreak.js'; import { MacrosParser } from '../macros.js'; +import { t } from '../i18n.js'; /** @typedef {import('./SlashCommand.js').NamedArgumentsCapture} NamedArgumentsCapture */ /** @typedef {import('./SlashCommand.js').NamedArguments} NamedArguments */ @@ -496,7 +497,8 @@ export class SlashCommandParser { (li.querySelector('tt').remove(),li.innerHTML), )); for (const macro of MacrosParser) { - options.push(new MacroAutoCompleteOption(macro.name, `{{${macro.name}}}`, macro.description || 'No description provided')); + if (options.find(it => it.name === macro.key)) continue; + options.push(new MacroAutoCompleteOption(macro.key, `{{${macro.key}}}`, macro.description || t`No description provided`)); } const result = new AutoCompleteNameResult( macro.name,