From 9184947c611b197290b7ccee4a0fd7644a877dc6 Mon Sep 17 00:00:00 2001 From: Benjamin Oddou Date: Sun, 16 Nov 2025 15:39:25 +0100 Subject: [PATCH 1/2] feat(i18n): internationalize completion snippets --- src/app/src/locales/en.json | 11 +++++ src/app/src/locales/fr.json | 11 +++++ src/app/src/utils/monaco/mdc-compilation.ts | 52 +++++++++++---------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/app/src/locales/en.json b/src/app/src/locales/en.json index 4349e8a..5522a78 100644 --- a/src/app/src/locales/en.json +++ b/src/app/src/locales/en.json @@ -164,6 +164,17 @@ "image": "Image" }, "writeSomething": "Write Something", + "snippets": { + "title": "title", + "item1": "Item 1", + "item2": "Item 2", + "language": "language", + "code": "code", + "link": "link", + "alt": "alt", + "src": "src", + "value": "value" + }, "docs": { "path": "Path in project:", "props": "Props", diff --git a/src/app/src/locales/fr.json b/src/app/src/locales/fr.json index 99266d1..107305a 100644 --- a/src/app/src/locales/fr.json +++ b/src/app/src/locales/fr.json @@ -164,6 +164,17 @@ "image": "Image" }, "writeSomething": "Écrivez quelque chose", + "snippets": { + "title": "titre", + "item1": "Élément 1", + "item2": "Élément 2", + "language": "langage", + "code": "code", + "link": "lien", + "alt": "alt", + "src": "src", + "value": "valeur" + }, "docs": { "path": "Chemin dans le projet :", "props": "Props", diff --git a/src/app/src/utils/monaco/mdc-compilation.ts b/src/app/src/utils/monaco/mdc-compilation.ts index 10eeb2e..2454219 100644 --- a/src/app/src/utils/monaco/mdc-compilation.ts +++ b/src/app/src/utils/monaco/mdc-compilation.ts @@ -126,7 +126,7 @@ export const setupSuggestion = ( const componentProps = findComponentProps(componentName, projectComponents.value as ComponentMeta[]) const suggestions = componentProps.filter(prop => typeof attributes[prop.name] === 'undefined').map((prop) => { - const insertText = `${prop.name}="\${1:${unwrapQuotes(prop.default || 'value')}}"` + const insertText = `${prop.name}="\${1:${unwrapQuotes(prop.default || t('studio.monaco.snippets.value'))}}"` return { label: prop.name, filterText: prop.name, @@ -162,13 +162,17 @@ function findComponentProps(componentName: string, components: ComponentMeta[]) return component.meta.props || [] } +function normalizeText(str: string) { + return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036F]/g, '').replace(' ', '-') +} + function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', t: TFunction): CompletionItem[] { return [ { label: t('studio.monaco.headings.h1'), - filterText: trigger + 'heading 1', + filterText: trigger + normalizeText(t('studio.monaco.headings.h1')), detail: '#', - insertText: '# ${1:title}', + insertText: `# \${1:${t('studio.monaco.snippets.title')}}`, kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, type: 'block', @@ -176,9 +180,9 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.headings.h2'), - filterText: trigger + 'heading 2', + filterText: trigger + normalizeText(t('studio.monaco.headings.h2')), detail: '##', - insertText: '## ${1:title}', + insertText: `## \${1:${t('studio.monaco.snippets.title')}}`, kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, type: 'block', @@ -186,9 +190,9 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.headings.h3'), - filterText: trigger + 'heading 3', + filterText: trigger + normalizeText(t('studio.monaco.headings.h3')), detail: '###', - insertText: '### ${1:title}', + insertText: `### \${1:${t('studio.monaco.snippets.title')}}`, kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, type: 'block', @@ -196,8 +200,8 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.styles.bold'), - filterText: trigger + 'bold', - insertText: '**${1:title}**', + filterText: trigger + normalizeText(t('studio.monaco.styles.bold')), + insertText: `**\${1:${t('studio.monaco.snippets.title')}}**`, detail: '**', kind: monaco.languages.CompletionItemKind.Field, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, @@ -206,8 +210,8 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.styles.italic'), - filterText: trigger + 'italic', - insertText: '_${1:title}_', + filterText: trigger + normalizeText(t('studio.monaco.styles.italic')), + insertText: `_\${1:${t('studio.monaco.snippets.title')}}_`, detail: '_', kind: monaco.languages.CompletionItemKind.Field, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, @@ -216,7 +220,7 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.other.emojis'), - filterText: trigger + 'emoji', + filterText: trigger + normalizeText(t('studio.monaco.other.emojis')), insertText: ':${1}:', detail: ':', kind: monaco.languages.CompletionItemKind.Field, @@ -226,8 +230,8 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.lists.bulleted'), - filterText: trigger + 'bulleted-list', - insertText: '- ${1:Item 1}\n- ${2:Item 2}\n\n${3}', + filterText: trigger + normalizeText(t('studio.monaco.lists.bulleted')), + insertText: `- \${1:${t('studio.monaco.snippets.item1')}}\n- \${2:${t('studio.monaco.snippets.item2')}}\n\n\${3}`, detail: '-', kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, @@ -236,8 +240,8 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.lists.numbered'), - filterText: trigger + 'numbered-list', - insertText: '1. ${1:Item 1}\n2. ${2:Item 2}\n\n${3}', + filterText: trigger + normalizeText(t('studio.monaco.lists.numbered')), + insertText: `1. \${1:${t('studio.monaco.snippets.item1')}}\n2. \${2:${t('studio.monaco.snippets.item2')}}\n\n\${3}`, detail: '1.', kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, @@ -246,7 +250,7 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.other.blockquote'), - filterText: trigger + 'blockquote', + filterText: trigger + normalizeText(t('studio.monaco.other.blockquote')), insertText: '> ${1}\n> ${2}\n\n${3}', detail: '>', kind: monaco.languages.CompletionItemKind.Function, @@ -256,8 +260,8 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.other.code'), - filterText: trigger + 'code', - insertText: '```${1:language}\n${2:code}\n```\n\n${3}', + filterText: trigger + normalizeText(t('studio.monaco.other.code')), + insertText: '```${1:' + t('studio.monaco.snippets.language') + '}\n${2:' + t('studio.monaco.snippets.code') + '}\n```\n\n${3}', detail: '```', kind: monaco.languages.CompletionItemKind.Function, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, @@ -266,7 +270,7 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.other.inlineCode'), - filterText: trigger + 'code-inline', + filterText: trigger + normalizeText(t('studio.monaco.other.inlineCode')), insertText: '`$1` $2', detail: '`', kind: monaco.languages.CompletionItemKind.Field, @@ -276,23 +280,23 @@ function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', }, { label: t('studio.monaco.other.link'), - filterText: trigger + 'link', + filterText: trigger + normalizeText(t('studio.monaco.other.link')), detail: '[]()', documentation: [ '[Studio](https://content.nuxt.com)', ].join('\n'), kind: monaco.languages.CompletionItemKind.Field, - insertText: '[${1:title}](${2:link})', + insertText: `[\${1:${t('studio.monaco.snippets.title')}}](\${2:${t('studio.monaco.snippets.link')}})`, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, type: 'inline', range, }, { label: t('studio.monaco.other.image'), - filterText: trigger + 'image', + filterText: trigger + normalizeText(t('studio.monaco.other.image')), detail: '![]()', kind: monaco.languages.CompletionItemKind.Field, - insertText: '![${1:alt}](${2:src})', + insertText: `![\${1:${t('studio.monaco.snippets.alt')}}](\${2:${t('studio.monaco.snippets.src')}})`, insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet, type: 'inline', range, From 455b4d1dc3ebfb8d41084d2021be631d9f66011c Mon Sep 17 00:00:00 2001 From: Benjamin Oddou <85166574+BenjaminOddou@users.noreply.github.com> Date: Sun, 16 Nov 2025 15:46:42 +0100 Subject: [PATCH 2/2] Update src/app/src/utils/monaco/mdc-compilation.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- src/app/src/utils/monaco/mdc-compilation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/src/utils/monaco/mdc-compilation.ts b/src/app/src/utils/monaco/mdc-compilation.ts index 2454219..2f10c9b 100644 --- a/src/app/src/utils/monaco/mdc-compilation.ts +++ b/src/app/src/utils/monaco/mdc-compilation.ts @@ -163,7 +163,7 @@ function findComponentProps(componentName: string, components: ComponentMeta[]) } function normalizeText(str: string) { - return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036F]/g, '').replace(' ', '-') + return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036F]/g, '').replace(/ /g, '-') } function getGlobalCompletionItems(monaco: Monaco, range: IRange, trigger = '/', t: TFunction): CompletionItem[] {