diff --git a/src/features/translation.ts b/src/features/translation.ts index f97b4aa1..9469ddbb 100644 --- a/src/features/translation.ts +++ b/src/features/translation.ts @@ -4,6 +4,7 @@ import { getTranslationItemByName, getTranslationPathByName, getTranslations, + NestedTranslationItem, TranslationItem, } from "@src/repositories/translations"; import { config } from "@src/support/config"; @@ -113,6 +114,38 @@ const getTranslationItemByLang = ( ); }; +const getNestedTranslationItem = ( + match: string, +): NestedTranslationItem | undefined => { + const translations = getTranslations().items.translations; + + const firstNestedMatch = Object.keys(translations).find((key) => + key.startsWith(match.replaceAll("\\", "") + "."), + ); + + return firstNestedMatch + ? ({ + translationItem: getTranslationItemByName(firstNestedMatch), + isNested: true, + } as NestedTranslationItem) + : undefined; +}; + +const getTranslationItem = ( + match: string, +): NestedTranslationItem | undefined => { + // First, try to find exact match + const translationItem = getTranslationItemByName(match); + + // If we can't find exact match, try to find a first nested element + return translationItem + ? ({ + translationItem: translationItem, + isNested: false, + } as NestedTranslationItem) + : getNestedTranslationItem(match); +}; + export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => { return detectInDoc( doc, @@ -123,14 +156,16 @@ export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => { return null; } - const translation = getTranslationItemByName(param.value); + const translationItem = getTranslationItem( + param.value, + )?.translationItem; - if (!translation) { + if (!translationItem) { return null; } const def = getTranslationItemByLang( - translation, + translationItem, getLang(item as AutocompleteParsingResult.MethodCall), ); @@ -149,17 +184,19 @@ export const hoverProvider: HoverProvider = ( pos: vscode.Position, ): vscode.ProviderResult => { return findHoverMatchesInDoc(doc, pos, toFind, getTranslations, (match) => { - const item = getTranslationItemByName(match); + const translationItem = getTranslationItem(match); - if (!item) { + if (!translationItem?.translationItem) { return null; } - const text = Object.entries(item) + const text = Object.entries(translationItem.translationItem) .filter(([key]) => key !== "default") .map(([key, translation]) => { return [ - `\`${key}\`: ${translation.value}`, + ...(!translationItem.isNested + ? [`\`${key}\`: ${translation.value}`] + : []), `[${relativePath(translation.path)}](${vscode.Uri.file( translation.path, ).with({ @@ -185,9 +222,11 @@ export const diagnosticProvider = ( return null; } - const translation = getTranslationItemByName(param.value); + const translationItem = getTranslationItem( + param.value, + )?.translationItem; - if (translation) { + if (translationItem) { return null; } diff --git a/src/repositories/translations.ts b/src/repositories/translations.ts index a55b3263..b5aecc00 100644 --- a/src/repositories/translations.ts +++ b/src/repositories/translations.ts @@ -3,6 +3,11 @@ import { projectPath } from "@src/support/project"; import { waitForValue } from "@src/support/util"; import { repository } from "."; +export interface NestedTranslationItem { + translationItem: TranslationItem | undefined; + isNested: boolean; +} + export interface TranslationItem { [key: string]: { value: string;