feat(i18n): add Russian language support

This commit is contained in:
Fazil
2025-12-12 21:10:57 +03:00
parent 8b29dd130e
commit 026fd468b1
5 changed files with 1173 additions and 7 deletions

View File

@@ -10,19 +10,21 @@ The `/language` command allows you to customize the language settings for both t
To change the UI language of Qwen Code, use the `ui` subcommand: To change the UI language of Qwen Code, use the `ui` subcommand:
``` ```
/language ui [zh-CN|en-US] /language ui [zh-CN|en-US|ru-RU]
``` ```
### Available UI Languages ### Available UI Languages
- **zh-CN**: Simplified Chinese (简体中文) - **zh-CN**: Simplified Chinese (简体中文)
- **en-US**: English - **en-US**: English
- **ru-RU**: Russian (Русский)
### Examples ### Examples
``` ```
/language ui zh-CN # Set UI language to Simplified Chinese /language ui zh-CN # Set UI language to Simplified Chinese
/language ui en-US # Set UI language to English /language ui en-US # Set UI language to English
/language ui ru-RU # Set UI language to Russian
``` ```
### UI Language Subcommands ### UI Language Subcommands
@@ -31,6 +33,7 @@ You can also use direct subcommands for convenience:
- `/language ui zh-CN` or `/language ui zh` or `/language ui 中文` - `/language ui zh-CN` or `/language ui zh` or `/language ui 中文`
- `/language ui en-US` or `/language ui en` or `/language ui english` - `/language ui en-US` or `/language ui en` or `/language ui english`
- `/language ui ru-RU` or `/language ui ru` or `/language ui русский`
## LLM Output Language Settings ## LLM Output Language Settings

View File

@@ -191,6 +191,7 @@ const SETTINGS_SCHEMA = {
{ value: 'auto', label: 'Auto (detect from system)' }, { value: 'auto', label: 'Auto (detect from system)' },
{ value: 'en', label: 'English' }, { value: 'en', label: 'English' },
{ value: 'zh', label: '中文 (Chinese)' }, { value: 'zh', label: '中文 (Chinese)' },
{ value: 'ru', label: 'Русский (Russian)' },
], ],
}, },
}, },

View File

@@ -9,7 +9,7 @@ import * as path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url'; import { fileURLToPath, pathToFileURL } from 'node:url';
import { homedir } from 'node:os'; import { homedir } from 'node:os';
export type SupportedLanguage = 'en' | 'zh' | string; // Allow custom language codes export type SupportedLanguage = 'en' | 'zh' | 'ru' | string; // Allow custom language codes
// State // State
let currentLanguage: SupportedLanguage = 'en'; let currentLanguage: SupportedLanguage = 'en';
@@ -51,10 +51,12 @@ export function detectSystemLanguage(): SupportedLanguage {
const envLang = process.env['QWEN_CODE_LANG'] || process.env['LANG']; const envLang = process.env['QWEN_CODE_LANG'] || process.env['LANG'];
if (envLang?.startsWith('zh')) return 'zh'; if (envLang?.startsWith('zh')) return 'zh';
if (envLang?.startsWith('en')) return 'en'; if (envLang?.startsWith('en')) return 'en';
if (envLang?.startsWith('ru')) return 'ru';
try { try {
const locale = Intl.DateTimeFormat().resolvedOptions().locale; const locale = Intl.DateTimeFormat().resolvedOptions().locale;
if (locale.startsWith('zh')) return 'zh'; if (locale.startsWith('zh')) return 'zh';
if (locale.startsWith('ru')) return 'ru';
} catch { } catch {
// Fallback to default // Fallback to default
} }

File diff suppressed because it is too large Load Diff

View File

@@ -130,6 +130,7 @@ async function setUiLanguage(
const langDisplayNames: Record<SupportedLanguage, string> = { const langDisplayNames: Record<SupportedLanguage, string> = {
zh: '中文zh-CN', zh: '中文zh-CN',
en: 'Englishen-US', en: 'Englishen-US',
ru: 'Русский (ru-RU)',
}; };
return { return {
@@ -216,7 +217,7 @@ export const languageCommand: SlashCommand = {
: t('LLM output language not set'), : t('LLM output language not set'),
'', '',
t('Available subcommands:'), t('Available subcommands:'),
` /language ui [zh-CN|en-US] - ${t('Set UI language')}`, ` /language ui [zh-CN|en-US|ru-RU] - ${t('Set UI language')}`,
` /language output <language> - ${t('Set LLM output language')}`, ` /language output <language> - ${t('Set LLM output language')}`,
].join('\n'); ].join('\n');
@@ -232,7 +233,7 @@ export const languageCommand: SlashCommand = {
const subcommand = parts[0].toLowerCase(); const subcommand = parts[0].toLowerCase();
if (subcommand === 'ui') { if (subcommand === 'ui') {
// Handle /language ui [zh-CN|en-US] // Handle /language ui [zh-CN|en-US|ru-RU]
if (parts.length === 1) { if (parts.length === 1) {
// Show UI language subcommand help // Show UI language subcommand help
return { return {
@@ -241,11 +242,12 @@ export const languageCommand: SlashCommand = {
content: [ content: [
t('Set UI language'), t('Set UI language'),
'', '',
t('Usage: /language ui [zh-CN|en-US]'), t('Usage: /language ui [zh-CN|en-US|ru-RU]'),
'', '',
t('Available options:'), t('Available options:'),
t(' - zh-CN: Simplified Chinese'), t(' - zh-CN: Simplified Chinese'),
t(' - en-US: English'), t(' - en-US: English'),
t(' - ru-RU: Russian'),
'', '',
t( t(
'To request additional UI language packs, please open an issue on GitHub.', 'To request additional UI language packs, please open an issue on GitHub.',
@@ -266,11 +268,18 @@ export const languageCommand: SlashCommand = {
langArg === 'zh-cn' langArg === 'zh-cn'
) { ) {
targetLang = 'zh'; targetLang = 'zh';
} else if (
langArg === 'ru' ||
langArg === 'ru-RU' ||
langArg === 'russian' ||
langArg === 'русский'
) {
targetLang = 'ru';
} else { } else {
return { return {
type: 'message', type: 'message',
messageType: 'error', messageType: 'error',
content: t('Invalid language. Available: en-US, zh-CN'), content: t('Invalid language. Available: en-US, zh-CN, ru-RU'),
}; };
} }
@@ -307,13 +316,20 @@ export const languageCommand: SlashCommand = {
langArg === 'zh-cn' langArg === 'zh-cn'
) { ) {
targetLang = 'zh'; targetLang = 'zh';
} else if (
langArg === 'ru' ||
langArg === 'ru-RU' ||
langArg === 'russian' ||
langArg === 'русский'
) {
targetLang = 'ru';
} else { } else {
return { return {
type: 'message', type: 'message',
messageType: 'error', messageType: 'error',
content: [ content: [
t('Invalid command. Available subcommands:'), t('Invalid command. Available subcommands:'),
' - /language ui [zh-CN|en-US] - ' + t('Set UI language'), ' - /language ui [zh-CN|en-US|ru-RU] - ' + t('Set UI language'),
' - /language output <language> - ' + t('Set LLM output language'), ' - /language output <language> - ' + t('Set LLM output language'),
].join('\n'), ].join('\n'),
}; };
@@ -423,6 +439,29 @@ export const languageCommand: SlashCommand = {
return setUiLanguage(context, 'en'); return setUiLanguage(context, 'en');
}, },
}, },
{
name: 'ru-RU',
altNames: ['ru', 'russian', 'русский'],
get description() {
return t('Set UI language to Russian (ru-RU)');
},
kind: CommandKind.BUILT_IN,
action: async (
context: CommandContext,
args: string,
): Promise<MessageActionReturn> => {
if (args.trim().length > 0) {
return {
type: 'message',
messageType: 'error',
content: t(
'Language subcommands do not accept additional arguments.',
),
};
}
return setUiLanguage(context, 'ru');
},
},
], ],
}, },
{ {