Merge pull request #1238 from fazilus/feat/russian

feat(i18n): add Russian language support
This commit is contained in:
pomelo
2025-12-13 11:44:02 +08:00
committed by GitHub
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:
```
/language ui [zh-CN|en-US]
/language ui [zh-CN|en-US|ru-RU]
```
### Available UI Languages
- **zh-CN**: Simplified Chinese (简体中文)
- **en-US**: English
- **ru-RU**: Russian (Русский)
### Examples
```
/language ui zh-CN # Set UI language to Simplified Chinese
/language ui en-US # Set UI language to English
/language ui ru-RU # Set UI language to Russian
```
### 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 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

View File

@@ -191,6 +191,7 @@ const SETTINGS_SCHEMA = {
{ value: 'auto', label: 'Auto (detect from system)' },
{ value: 'en', label: 'English' },
{ 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 { 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
let currentLanguage: SupportedLanguage = 'en';
@@ -51,10 +51,12 @@ export function detectSystemLanguage(): SupportedLanguage {
const envLang = process.env['QWEN_CODE_LANG'] || process.env['LANG'];
if (envLang?.startsWith('zh')) return 'zh';
if (envLang?.startsWith('en')) return 'en';
if (envLang?.startsWith('ru')) return 'ru';
try {
const locale = Intl.DateTimeFormat().resolvedOptions().locale;
if (locale.startsWith('zh')) return 'zh';
if (locale.startsWith('ru')) return 'ru';
} catch {
// 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> = {
zh: '中文zh-CN',
en: 'Englishen-US',
ru: 'Русский (ru-RU)',
};
return {
@@ -216,7 +217,7 @@ export const languageCommand: SlashCommand = {
: t('LLM output language not set'),
'',
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')}`,
].join('\n');
@@ -232,7 +233,7 @@ export const languageCommand: SlashCommand = {
const subcommand = parts[0].toLowerCase();
if (subcommand === 'ui') {
// Handle /language ui [zh-CN|en-US]
// Handle /language ui [zh-CN|en-US|ru-RU]
if (parts.length === 1) {
// Show UI language subcommand help
return {
@@ -241,11 +242,12 @@ export const languageCommand: SlashCommand = {
content: [
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(' - zh-CN: Simplified Chinese'),
t(' - en-US: English'),
t(' - ru-RU: Russian'),
'',
t(
'To request additional UI language packs, please open an issue on GitHub.',
@@ -266,11 +268,18 @@ export const languageCommand: SlashCommand = {
langArg === 'zh-cn'
) {
targetLang = 'zh';
} else if (
langArg === 'ru' ||
langArg === 'ru-RU' ||
langArg === 'russian' ||
langArg === 'русский'
) {
targetLang = 'ru';
} else {
return {
type: 'message',
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'
) {
targetLang = 'zh';
} else if (
langArg === 'ru' ||
langArg === 'ru-RU' ||
langArg === 'russian' ||
langArg === 'русский'
) {
targetLang = 'ru';
} else {
return {
type: 'message',
messageType: 'error',
content: [
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'),
].join('\n'),
};
@@ -423,6 +439,29 @@ export const languageCommand: SlashCommand = {
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');
},
},
],
},
{