fix(i18n): correct Korean mistranslations and particle spacing (#5761)
This commit is contained in:
parent
bbacb694cd
commit
4c5c2f4df3
|
|
@ -0,0 +1,50 @@
|
|||
// Latin workflow/brand terms that get a space inserted around them when CJK machine
|
||||
// translation glues them to native text (see applyCjkLatinTermSpacing).
|
||||
export const CJK_LATIN_SPACED_TERMS = [
|
||||
'Issues',
|
||||
'Issue',
|
||||
'Terminal',
|
||||
'Terminals',
|
||||
'terminal',
|
||||
'terminals',
|
||||
'Agents',
|
||||
'Agent',
|
||||
'agents',
|
||||
'agent',
|
||||
'Markdown',
|
||||
'markdown',
|
||||
'Repos',
|
||||
'Repo',
|
||||
'repos',
|
||||
'repo',
|
||||
'Commits',
|
||||
'Commit',
|
||||
'commits',
|
||||
'commit',
|
||||
'Linear',
|
||||
'GitHub',
|
||||
'GitLab',
|
||||
'Jira',
|
||||
'Claude',
|
||||
'Claude Code',
|
||||
'Codex',
|
||||
'Gemini',
|
||||
'Kimi',
|
||||
'OpenCode',
|
||||
'Orca',
|
||||
'Cursor',
|
||||
'Bitbucket',
|
||||
'Tailscale',
|
||||
'Kagi',
|
||||
'SSH',
|
||||
'WSL',
|
||||
'PR',
|
||||
'MR',
|
||||
'REST',
|
||||
'HEAD',
|
||||
'Bash',
|
||||
'PowerShell',
|
||||
'Git AI Author',
|
||||
'Token',
|
||||
'token'
|
||||
]
|
||||
|
|
@ -87,6 +87,10 @@ export const KO_VALUE_OVERRIDES = {
|
|||
Start: '시작',
|
||||
Work: '작업',
|
||||
Show: '표시',
|
||||
Hide: '숨기기',
|
||||
Import: '가져오기',
|
||||
import: '가져오기',
|
||||
'Import…': '가져오기…',
|
||||
Pass: '통과',
|
||||
Maintain: '유지',
|
||||
Approve: '승인',
|
||||
|
|
|
|||
|
|
@ -134,4 +134,53 @@ describe('locale-translation-policy ko round 5', () => {
|
|||
})
|
||||
).toBe('로컬 프로젝트, Git repo 또는 repos가 많은 폴더')
|
||||
})
|
||||
|
||||
it('re-glues Korean particles after Latin terms without gluing content words', () => {
|
||||
// A wrong space before the 에 particle is re-glued onto the Latin term.
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.StarNagCard.cf82170065',
|
||||
enValue: 'Could not star the repo. Make sure',
|
||||
localeValue: 'repo 에 스타를 표시할 수 없습니다. 다음을 확인하세요',
|
||||
locale: 'ko'
|
||||
})
|
||||
).toBe('repo에 스타를 표시할 수 없습니다. 다음을 확인하세요')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.github.project.ProjectCell.4b5b871da8',
|
||||
enValue: 'No labels in this repo.',
|
||||
localeValue: '이 repo 에는 라벨이 없습니다.',
|
||||
locale: 'ko'
|
||||
})
|
||||
).toBe('이 repo에는 라벨이 없습니다.')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.terminal.pane.CloseTerminalDialog.6b9a6975f8',
|
||||
enValue:
|
||||
'The terminal still has a running process. If you close the terminal, the process will be killed.',
|
||||
localeValue:
|
||||
'terminal 에는 여전히 실행 중인 프로세스가 있습니다. terminal을 닫으면 프로세스가 종료됩니다.',
|
||||
locale: 'ko'
|
||||
})
|
||||
).toBe(
|
||||
'terminal에는 여전히 실행 중인 프로세스가 있습니다. terminal을 닫으면 프로세스가 종료됩니다.'
|
||||
)
|
||||
// A correct space before a content word that merely starts with a particle syllable is kept.
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.JiraIssueWorkspace.76513c7898',
|
||||
enValue: 'Close Jira issue preview',
|
||||
localeValue: 'Jira 이슈 미리보기 닫기',
|
||||
locale: 'ko'
|
||||
})
|
||||
).toBe('Jira 이슈 미리보기 닫기')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.GitHubItemDialog.3ab6ac0fc8',
|
||||
enValue: 'Preview and edit the selected GitHub issue or pull request.',
|
||||
localeValue: '선택한 GitHub 이슈 또는 PR을 미리보기하고 편집합니다.',
|
||||
locale: 'ko'
|
||||
})
|
||||
).toBe('선택한 GitHub 이슈 또는 PR을 미리보기하고 편집합니다.')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { CJK_LATIN_SPACED_TERMS } from './locale-cjk-latin-spaced-terms.mjs'
|
||||
import { isScreenCursorContext } from './locale-screen-cursor-exemptions.mjs'
|
||||
import { LOCALE_KEY_OVERRIDES } from './locale-key-overrides.mjs'
|
||||
import { LOCALE_PHRASE_FIXES } from './locale-phrase-fixes.mjs'
|
||||
|
|
@ -20,6 +21,7 @@ export const NEVER_TRANSLATE_VALUES = new Set([
|
|||
'Agents',
|
||||
'Aider',
|
||||
'Amp',
|
||||
'Android',
|
||||
'Antigravity',
|
||||
'Auggie',
|
||||
'Autohand Code',
|
||||
|
|
@ -35,6 +37,8 @@ export const NEVER_TRANSLATE_VALUES = new Set([
|
|||
'Droid',
|
||||
'Devin',
|
||||
'Gemini',
|
||||
'Git',
|
||||
'Git Bash',
|
||||
'GitHub Copilot',
|
||||
'GitLab',
|
||||
'Goose',
|
||||
|
|
@ -68,6 +72,7 @@ export const NEVER_TRANSLATE_VALUES = new Set([
|
|||
'Zed',
|
||||
'agent',
|
||||
'agents',
|
||||
'android',
|
||||
'codex',
|
||||
'commit',
|
||||
'commits',
|
||||
|
|
@ -188,6 +193,7 @@ export const BRAND_MISTRANSLATIONS = {
|
|||
Goose: ['거위'],
|
||||
Pi: ['파이'],
|
||||
'GitHub Copilot': ['GitHub 코파일럿', '코파일럿'],
|
||||
Git: ['힘내'],
|
||||
Discord: ['디스코드'],
|
||||
Linear: ['선형'],
|
||||
Agent: ['에이전트'],
|
||||
|
|
@ -331,55 +337,6 @@ export const NATIVE_PICKER_LABELS = {
|
|||
es: { chinese: '中文(简体)', korean: '한국어', japanese: '日本語', spanish: 'Español' }
|
||||
}
|
||||
|
||||
const CJK_LATIN_SPACED_TERMS = [
|
||||
'Issues',
|
||||
'Issue',
|
||||
'Terminal',
|
||||
'Terminals',
|
||||
'terminal',
|
||||
'terminals',
|
||||
'Agents',
|
||||
'Agent',
|
||||
'agents',
|
||||
'agent',
|
||||
'Markdown',
|
||||
'markdown',
|
||||
'Repos',
|
||||
'Repo',
|
||||
'repos',
|
||||
'repo',
|
||||
'Commits',
|
||||
'Commit',
|
||||
'commits',
|
||||
'commit',
|
||||
'Linear',
|
||||
'GitHub',
|
||||
'GitLab',
|
||||
'Jira',
|
||||
'Claude',
|
||||
'Claude Code',
|
||||
'Codex',
|
||||
'Gemini',
|
||||
'Kimi',
|
||||
'OpenCode',
|
||||
'Orca',
|
||||
'Cursor',
|
||||
'Bitbucket',
|
||||
'Tailscale',
|
||||
'Kagi',
|
||||
'SSH',
|
||||
'WSL',
|
||||
'PR',
|
||||
'MR',
|
||||
'REST',
|
||||
'HEAD',
|
||||
'Bash',
|
||||
'PowerShell',
|
||||
'Git AI Author',
|
||||
'Token',
|
||||
'token'
|
||||
]
|
||||
|
||||
const CJK_LATIN_SPACED_TERM_PATTERN = CJK_LATIN_SPACED_TERMS.join('|')
|
||||
|
||||
export function isEnglishOnlyKey(key) {
|
||||
|
|
@ -465,9 +422,11 @@ function applyCjkLatinTermSpacing(localeValue, locale) {
|
|||
'$1 $2'
|
||||
)
|
||||
if (locale === 'ko') {
|
||||
// Korean particles attach to the noun (no space) only when the particle is a complete token at a
|
||||
// boundary — re-glue "Orca 에"/"PR 을"/"에서는" but keep "Jira 이슈"/"Orca 로고"/"agent 에뮬레이터".
|
||||
result = result.replace(
|
||||
new RegExp(
|
||||
`(${CJK_LATIN_SPACED_TERM_PATTERN}) (가|이|은|는|을|를|와|과|의|로|으로|에서|에게|도|만|부터|까지)`,
|
||||
`(${CJK_LATIN_SPACED_TERM_PATTERN}) ((?:에서|에게|에는|에선|으로|로서|로써|부터|까지|보다|처럼|은|는|이|가|을|를|와|과|의|에|로|도|만)+)(?=$|[\\s.,!?…·:;)\\]}"'」』])`,
|
||||
'g'
|
||||
),
|
||||
'$1$2'
|
||||
|
|
|
|||
|
|
@ -3668,7 +3668,6 @@
|
|||
"1a0eec0d35": "Status",
|
||||
"b5536d5a88": "Tasks",
|
||||
"8d62c68b35": "Notes",
|
||||
"automation": "Automation",
|
||||
"2d74665a56": "Ports",
|
||||
"65a9820bd1": "Agent statuses",
|
||||
"219ebf1961": "Branch name"
|
||||
|
|
@ -11391,7 +11390,15 @@
|
|||
"openReviewExternally": "Open {{value0}} externally",
|
||||
"summary": "{{value0}} attached · {{value1}} with PR/MR · {{value2}} attention · {{value3}} pending · {{value4}} passing · {{value5}} no PR · {{value6}} unknown",
|
||||
"showDetails": "Show {{value0}} PR check details",
|
||||
"hideDetails": "Hide {{value0}} PR check details"
|
||||
"hideDetails": "Hide {{value0}} PR check details",
|
||||
"reviewChecks": "Review checks",
|
||||
"allChecksPassing": "all checks passing",
|
||||
"oneWorktree": "1 worktree",
|
||||
"worktreeCount": "{{value0}} worktrees",
|
||||
"oneFailing": "1 failing",
|
||||
"failingCount": "{{value0}} failing",
|
||||
"onePending": "1 pending",
|
||||
"pendingCount": "{{value0}} pending"
|
||||
},
|
||||
"parentPrChecks": {
|
||||
"rowSummary": {
|
||||
|
|
|
|||
|
|
@ -3656,8 +3656,7 @@
|
|||
"automation": "Automation",
|
||||
"2d74665a56": "Puertos",
|
||||
"65a9820bd1": "Estados del agente",
|
||||
"219ebf1961": "Nombre de rama",
|
||||
"automation": "Automation"
|
||||
"219ebf1961": "Nombre de rama"
|
||||
},
|
||||
"SshDisconnectedDialog": {
|
||||
"ca4a7892af": "Conectando...",
|
||||
|
|
@ -11391,7 +11390,15 @@
|
|||
"openReviewExternally": "Abrir {{value0}} externamente",
|
||||
"summary": "{{value0}} adjuntos · {{value1}} con PR/MR · {{value2}} requieren atención · {{value3}} pendientes · {{value4}} correctos · {{value5}} sin PR · {{value6}} desconocidos",
|
||||
"showDetails": "Mostrar detalles de comprobaciones de PR de {{value0}}",
|
||||
"hideDetails": "Ocultar detalles de comprobaciones de PR de {{value0}}"
|
||||
"hideDetails": "Ocultar detalles de comprobaciones de PR de {{value0}}",
|
||||
"reviewChecks": "Review checks",
|
||||
"allChecksPassing": "all checks passing",
|
||||
"oneWorktree": "1 worktree",
|
||||
"worktreeCount": "{{value0}} worktrees",
|
||||
"oneFailing": "1 failing",
|
||||
"failingCount": "{{value0}} failing",
|
||||
"onePending": "1 pending",
|
||||
"pendingCount": "{{value0}} pending"
|
||||
},
|
||||
"parentPrChecks": {
|
||||
"rowSummary": {
|
||||
|
|
|
|||
|
|
@ -11390,7 +11390,15 @@
|
|||
"openReviewExternally": "{{value0}} を外部で開く",
|
||||
"summary": "{{value0}} 件添付 · PR/MR あり {{value1}} 件 · 要対応 {{value2}} 件 · 保留中 {{value3}} 件 · 成功 {{value4}} 件 · PR なし {{value5}} 件 · 不明 {{value6}} 件",
|
||||
"showDetails": "{{value0}} の PR チェック詳細を表示",
|
||||
"hideDetails": "{{value0}} の PR チェック詳細を非表示"
|
||||
"hideDetails": "{{value0}} の PR チェック詳細を非表示",
|
||||
"reviewChecks": "Review checks",
|
||||
"allChecksPassing": "all checks passing",
|
||||
"oneWorktree": "1 worktree",
|
||||
"worktreeCount": "{{value0}} worktrees",
|
||||
"oneFailing": "1 failing",
|
||||
"failingCount": "{{value0}} failing",
|
||||
"onePending": "1 pending",
|
||||
"pendingCount": "{{value0}} pending"
|
||||
},
|
||||
"parentPrChecks": {
|
||||
"rowSummary": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -11390,7 +11390,15 @@
|
|||
"openReviewExternally": "在外部打开 {{value0}}",
|
||||
"summary": "已附加 {{value0}} 个 · 有 PR/MR {{value1}} 个 · 需注意 {{value2}} 个 · 等待中 {{value3}} 个 · 通过 {{value4}} 个 · 无 PR {{value5}} 个 · 未知 {{value6}} 个",
|
||||
"showDetails": "显示 {{value0}} 的 PR 检查详情",
|
||||
"hideDetails": "隐藏 {{value0}} 的 PR 检查详情"
|
||||
"hideDetails": "隐藏 {{value0}} 的 PR 检查详情",
|
||||
"reviewChecks": "Review checks",
|
||||
"allChecksPassing": "all checks passing",
|
||||
"oneWorktree": "1 worktree",
|
||||
"worktreeCount": "{{value0}} worktrees",
|
||||
"oneFailing": "1 failing",
|
||||
"failingCount": "{{value0}} failing",
|
||||
"onePending": "1 pending",
|
||||
"pendingCount": "{{value0}} pending"
|
||||
},
|
||||
"parentPrChecks": {
|
||||
"rowSummary": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue