From 095c8446f889b8bdd69a66d4e4bfaf8206066374 Mon Sep 17 00:00:00 2001 From: raideer Date: Tue, 8 Apr 2025 20:22:39 +0300 Subject: [PATCH] feat: event name autocomplete --- CHANGELOG.md | 4 ++ .../XmlCompletionProviderProcessor.ts | 2 + src/completion/xml/EventCompletionProvider.ts | 47 +++++++++++++++++++ src/indexer/events/EventsIndexData.ts | 6 +++ 4 files changed, 59 insertions(+) create mode 100644 src/completion/xml/EventCompletionProvider.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e81131..5eb346a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to the "magento-toolbox" extension will be documented in thi Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. +## [Unreleased] + +- Added: Event name autocomplete + ## [1.5.0] - 2025-04-06 - Added: Class namespace autocomplete in XML files - Added: Module name autocomplete in module.xml files diff --git a/src/completion/XmlCompletionProviderProcessor.ts b/src/completion/XmlCompletionProviderProcessor.ts index e80a21f..2f0f17d 100644 --- a/src/completion/XmlCompletionProviderProcessor.ts +++ b/src/completion/XmlCompletionProviderProcessor.ts @@ -8,6 +8,7 @@ import { ModuleCompletionProvider } from './xml/ModuleCompletionProvider'; import { NamespaceCompletionProvider } from './xml/NamespaceCompletionProvider'; import { AclCompletionProvider } from './xml/AclCompletionProvider'; import { TemplateCompletionProvider } from './xml/TemplateCompletionProvider'; +import { EventCompletionProvider } from './xml/EventCompletionProvider'; export class XmlCompletionProviderProcessor extends XmlSuggestionProviderProcessor @@ -19,6 +20,7 @@ export class XmlCompletionProviderProcessor new NamespaceCompletionProvider(), new AclCompletionProvider(), new TemplateCompletionProvider(), + new EventCompletionProvider(), ]); } diff --git a/src/completion/xml/EventCompletionProvider.ts b/src/completion/xml/EventCompletionProvider.ts new file mode 100644 index 0000000..8df4077 --- /dev/null +++ b/src/completion/xml/EventCompletionProvider.ts @@ -0,0 +1,47 @@ +import { TextDocument, CompletionItem, CompletionItemKind, Range } from 'vscode'; +import IndexManager from 'indexer/IndexManager'; +import { XmlSuggestionProvider, CombinedCondition } from 'common/xml/XmlSuggestionProvider'; +import { XMLElement, XMLAttribute } from '@xml-tools/ast'; +import { AttributeNameMatches } from 'common/xml/suggestion/condition/AttributeNameMatches'; +import { ElementNameMatches } from 'common/xml/suggestion/condition/ElementNameMatches'; +import EventsIndexer from 'indexer/events/EventsIndexer'; + +export class EventCompletionProvider extends XmlSuggestionProvider { + public getFilePatterns(): string[] { + return ['**/etc/events.xml']; + } + + public getAttributeValueConditions(): CombinedCondition[] { + return [[new ElementNameMatches('event'), new AttributeNameMatches('name')]]; + } + + public getConfigKey(): string | undefined { + return 'provideXmlDefinitions'; + } + + public getSuggestionItems( + value: string, + range: Range, + document: TextDocument, + element: XMLElement, + attribute?: XMLAttribute + ): CompletionItem[] { + const eventIndexData = IndexManager.getIndexData(EventsIndexer.KEY); + + if (!eventIndexData) { + return []; + } + + const events = eventIndexData.getEventsByPrefix(value); + + if (!events) { + return []; + } + + return events.map(event => { + const item = new CompletionItem(event.name, CompletionItemKind.Value); + item.range = range; + return item; + }); + } +} diff --git a/src/indexer/events/EventsIndexData.ts b/src/indexer/events/EventsIndexData.ts index 9ba253c..ab603ba 100644 --- a/src/indexer/events/EventsIndexData.ts +++ b/src/indexer/events/EventsIndexData.ts @@ -2,6 +2,7 @@ import { Memoize } from 'typescript-memoize'; import EventsIndexer from './EventsIndexer'; import { Event } from './types'; import { AbstractIndexData } from 'indexer/AbstractIndexData'; +import { uniqBy } from 'lodash-es'; export class EventsIndexData extends AbstractIndexData { @Memoize({ tags: [EventsIndexer.KEY] }) @@ -17,6 +18,11 @@ export class EventsIndexData extends AbstractIndexData { return this.getEvents().find(event => event.name === eventName); } + public getEventsByPrefix(prefix: string): Event[] { + const events = this.getEvents().filter(event => event.name.startsWith(prefix)); + return uniqBy(events, 'name'); + } + public findEventsByObserverInstance(observerInstance: string): Event[] { return this.getEvents().filter(event => event.observers.some(observer => observer.instance === observerInstance)