Fix unnatural Japanese (ja) localization wording (#5589)
* Fix unnatural Japanese localization wording
- "Open in" submenu: bare で開く → アプリで開く
- "Assigned to me" filter: 私に割り当てられました → 私に割り当てられた Issue
- Use Latin "Issue" instead of katakana イシュー throughout (JP engineering convention)
- Terminal/theme cursor settings: render the screen cursor as カーソル, not the
Cursor product. The brand-protection revert (Cursor→カーソル→Cursor) now exempts
these keys/values so カーソル survives while the Cursor product stays Latin.
- GraphQL: グラフQL → GraphQL
- Assignee picker aria-label: {{value0}} に割り当てられました → {{value0}} に割り当て済み
Fixes are made in the locale repair policy (overrides / phrase fixes) and applied via
repair:ja-catalog so they persist across future catalog regeneration.
* Extract screen-cursor exemption into a focused module
Move the Cursor screen-vs-product discrimination (SCREEN_CURSOR_ENVALUES /
SCREEN_CURSOR_KEYS / isScreenCursorContext) out of locale-translation-policy.mjs
into locale-screen-cursor-exemptions.mjs to keep the policy file under the
max-lines limit. No behavior change.
* Fix PR/issue state badge wording in Japanese
"State: Closed" was 状態: 閉店 (a shop closing) — change to 状態: クローズ to match
how the Closed state is rendered elsewhere. Also align "State: Merged" (状態: 結合済み)
with the standard マージ済み used for git merges.
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
This commit is contained in:
parent
abc3037b6a
commit
5ff6bc9778
|
|
@ -11,6 +11,7 @@ export const JA_PHRASE_FIXES = [
|
|||
{ pattern: /端末/g, replacement: 'ターミナル', whenEnIncludes: 'erminal' },
|
||||
{ pattern: /シャチ:\/\//g, replacement: 'orca://', whenEnIncludes: 'orca://' },
|
||||
{ pattern: /線形/g, replacement: 'Linear', whenEnIncludes: 'Linear' },
|
||||
{ pattern: /グラフQL/g, replacement: 'GraphQL', whenEnIncludes: 'GraphQL' },
|
||||
{ pattern: /不和/g, replacement: 'Discord', whenEnIncludes: 'Discord' },
|
||||
{ pattern: /爽やか/g, replacement: '更新中', whenEnIncludes: 'Refreshing' },
|
||||
{ pattern: /殺害/g, replacement: '終了中', whenEnIncludes: 'Killing' },
|
||||
|
|
@ -238,5 +239,7 @@ export const JA_PHRASE_FIXES = [
|
|||
{ pattern: /を選択してください/g, replacement: 'を選択', whenEnIncludes: 'Choose' },
|
||||
{ pattern: /入力してください/g, replacement: '入力', whenEnIncludes: 'Enter' },
|
||||
{ pattern: /追加してください/g, replacement: '追加', whenEnIncludes: 'Add' },
|
||||
{ pattern: /試してください/g, replacement: '試す', whenEnIncludes: 'Try' }
|
||||
{ pattern: /試してください/g, replacement: '試す', whenEnIncludes: 'Try' },
|
||||
// Why: JP engineers use "Issue" in Latin, not katakana. Runs last so all *→イシュー fixes above normalize to Issue.
|
||||
{ pattern: /イシュー/g, replacement: 'Issue', whenEnIncludes: 'issue' }
|
||||
]
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@ export const JA_VALUE_OVERRIDES = {
|
|||
'No Linear issues found': 'Linear イシューが見つかりません',
|
||||
'Unable to load Linear issues': 'Linear イシューを読み込めません',
|
||||
'No Jira issues found': 'Jira イシューが見つかりません',
|
||||
issue: 'イシュー',
|
||||
issues: 'イシュー',
|
||||
Issues: 'イシュー',
|
||||
issue: 'Issue',
|
||||
issues: 'Issue',
|
||||
Issues: 'Issue',
|
||||
'Common emulator commands': 'よく使うエミュレータコマンド',
|
||||
'Pull request': 'PR',
|
||||
'pull request': 'PR',
|
||||
|
|
@ -223,5 +223,15 @@ export const JA_VALUE_OVERRIDES = {
|
|||
'Open job in GitLab': 'GitLab でジョブを開く',
|
||||
'Showing first 100 jobs': '最初の 100 件のジョブを表示しています',
|
||||
'Imported from Ghostty.': 'Ghostty からインポートしました。',
|
||||
'Claude Accounts': 'Claude アカウント'
|
||||
'Claude Accounts': 'Claude アカウント',
|
||||
// PR/issue state badges: "Closed" is クローズ (not 閉店 = a shop closing); align "Merged" with マージ済み.
|
||||
'State: Closed': '状態: クローズ',
|
||||
'State: Merged': '状態: マージ済み',
|
||||
// Terminal/theme cursor settings = the on-screen カーソル, not the Cursor product.
|
||||
'Cursor Text': 'カーソル文字',
|
||||
'Cursor color': 'カーソル色',
|
||||
'Cursor Opacity': 'カーソルの不透明度',
|
||||
'Cursor Shape': 'カーソル形状',
|
||||
'Blinking Cursor': 'カーソルの点滅',
|
||||
'Terminal Cursor': 'Terminal カーソル'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,15 @@ import { KO_KEY_OVERRIDES } from './locale-ko-key-overrides.mjs'
|
|||
// Key-specific overrides from high-visibility UI audit (P0/P1/P2).
|
||||
// Why: some fixes depend on full key context, not English value alone.
|
||||
export const LOCALE_KEY_OVERRIDES = {
|
||||
// "Open in" is a submenu header for "open in <app>"; bare で開く reads as broken JP.
|
||||
'auto.components.sidebar.WorktreeOpenInMenu.8009ab69a6': { ja: 'アプリで開く' },
|
||||
// "Assigned to me" filter; the MT past-passive 割り当てられました reads as a sentence, not a filter label.
|
||||
'auto.components.TaskPage.94f0339621': { ja: '私に割り当てられた Issue' },
|
||||
// aria-label describing the assignee picker state; the past-passive sentence reads oddly for a static label.
|
||||
'auto.components.TaskPage.bb63046423': { ja: '{{value0}} に割り当て済み' },
|
||||
// Bare "Cursor" terminal/theme settings = on-screen カーソル, not the Cursor product.
|
||||
'auto.components.settings.TerminalWindowSection.c9e1fdf42f': { ja: 'カーソル' },
|
||||
'auto.components.onboarding.ThemeStep.ab2a583a97': { ja: 'カーソル' },
|
||||
'menu.reportCrash': { ko: '크래시 신고...', zh: '报告崩溃...', ja: 'クラッシュを報告...' },
|
||||
'menu.showMobileButton': {
|
||||
ko: 'Orca 모바일 버튼 표시',
|
||||
|
|
@ -25,7 +34,7 @@ export const LOCALE_KEY_OVERRIDES = {
|
|||
ja: 'ワークツリーパレットを開く'
|
||||
},
|
||||
'menu.exploreOrca': { ko: 'Orca 둘러보기', zh: '探索 Orca', ja: 'Orca を探索' },
|
||||
'worktreeJumpPalette.matchLabel.issue': { ko: '이슈', zh: '议题', ja: 'イシュー' },
|
||||
'worktreeJumpPalette.matchLabel.issue': { ko: '이슈', zh: '议题', ja: 'Issue' },
|
||||
'worktreeJumpPalette.matchLabel.comment': { ko: '댓글', zh: '评论', ja: 'コメント' },
|
||||
'auto.hooks.useSettingsNavigationMetadata.13241992bd': {
|
||||
ko: '일반',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Distinguishes the on-screen cursor (カーソル) from the "Cursor" product so the brand
|
||||
// revert in the translation policy doesn't force terminal/theme cursor settings back to Latin.
|
||||
|
||||
// Multi-word "Cursor …" labels always mean the screen cursor, never the Cursor product.
|
||||
const SCREEN_CURSOR_ENVALUES = new Set([
|
||||
'Cursor Text',
|
||||
'Cursor color',
|
||||
'Cursor Opacity',
|
||||
'Cursor Shape',
|
||||
'Blinking Cursor',
|
||||
'Terminal Cursor'
|
||||
])
|
||||
|
||||
// Bare "Cursor" is ambiguous; these keys are the terminal/theme cursor settings (screen cursor).
|
||||
const SCREEN_CURSOR_KEYS = new Set([
|
||||
'auto.components.settings.TerminalWindowSection.c9e1fdf42f',
|
||||
'auto.components.onboarding.ThemeStep.ab2a583a97'
|
||||
])
|
||||
|
||||
export function isScreenCursorContext(brand, enValue, key) {
|
||||
if (brand !== 'Cursor') {
|
||||
return false
|
||||
}
|
||||
return SCREEN_CURSOR_ENVALUES.has(enValue) || SCREEN_CURSOR_KEYS.has(key)
|
||||
}
|
||||
|
|
@ -234,8 +234,8 @@ export const SEARCH_KEYWORD_OVERRIDES = {
|
|||
glab: 'glab',
|
||||
mr: 'MR',
|
||||
'azure devops': 'Azure DevOps',
|
||||
issue: 'イシュー',
|
||||
issues: 'イシュー',
|
||||
issue: 'Issue',
|
||||
issues: 'Issue',
|
||||
pr: 'PR',
|
||||
'pull request': 'PR',
|
||||
phone: 'スマートフォン',
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ describe('locale-translation-policy ja round 5', () => {
|
|||
localeValue: 'リクエスト、イシュー、ToDo、パイプラインをマージします。',
|
||||
locale: 'ja'
|
||||
})
|
||||
).toBe('MR、イシュー、ToDo、パイプラインは')
|
||||
).toBe('MR、Issue、ToDo、パイプラインは')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.GitLabItemDialog.98718490e4',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
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'
|
||||
import { SEARCH_KEYWORD_OVERRIDES } from './locale-search-keyword-overrides.mjs'
|
||||
|
|
@ -331,6 +332,8 @@ export const NATIVE_PICKER_LABELS = {
|
|||
}
|
||||
|
||||
const CJK_LATIN_SPACED_TERMS = [
|
||||
'Issues',
|
||||
'Issue',
|
||||
'Terminal',
|
||||
'Terminals',
|
||||
'terminal',
|
||||
|
|
@ -407,7 +410,7 @@ function includesPreservedLatinTerm(value, term) {
|
|||
return new RegExp(`(^|[^A-Za-z_])${escapeRegExp(term)}($|[^A-Za-z_])`).test(value)
|
||||
}
|
||||
|
||||
function applyBrandMistranslationFixes(enValue, localeValue, locale) {
|
||||
function applyBrandMistranslationFixes(enValue, localeValue, locale, key = '') {
|
||||
let result = localeValue
|
||||
const mistranslations = BRAND_MISTRANSLATIONS[locale] ?? {}
|
||||
|
||||
|
|
@ -417,6 +420,11 @@ function applyBrandMistranslationFixes(enValue, localeValue, locale) {
|
|||
if (!enValue.includes(brand)) {
|
||||
continue
|
||||
}
|
||||
// Why: terminal/theme "Cursor" labels name the on-screen カーソル, not the Cursor product —
|
||||
// skip the revert so カーソル survives for these settings.
|
||||
if (isScreenCursorContext(brand, enValue, key)) {
|
||||
continue
|
||||
}
|
||||
if (includesPreservedLatinTerm(result, brand)) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -483,7 +491,7 @@ export function repairTranslatedValue({ key, enValue, localeValue, locale }) {
|
|||
const keyOverride = LOCALE_KEY_OVERRIDES[key]?.[locale]
|
||||
if (keyOverride) {
|
||||
// Why: exact key overrides can still carry stale MT output, so glossary repairs remain the final gate.
|
||||
let result = applyBrandMistranslationFixes(enValue, keyOverride, locale)
|
||||
let result = applyBrandMistranslationFixes(enValue, keyOverride, locale, key)
|
||||
result = applyPhraseFixes(enValue, result, locale)
|
||||
if (['zh', 'ja', 'ko'].includes(locale)) {
|
||||
result = applyCjkLatinTermSpacing(result, locale)
|
||||
|
|
@ -493,7 +501,7 @@ export function repairTranslatedValue({ key, enValue, localeValue, locale }) {
|
|||
|
||||
const valueOverride = LOCALE_VALUE_OVERRIDES[locale]?.[enValue]
|
||||
if (valueOverride) {
|
||||
let result = applyBrandMistranslationFixes(enValue, valueOverride, locale)
|
||||
let result = applyBrandMistranslationFixes(enValue, valueOverride, locale, key)
|
||||
result = applyPhraseFixes(enValue, result, locale)
|
||||
if (['zh', 'ja', 'ko'].includes(locale)) {
|
||||
result = applyCjkLatinTermSpacing(result, locale)
|
||||
|
|
@ -514,7 +522,7 @@ export function repairTranslatedValue({ key, enValue, localeValue, locale }) {
|
|||
}
|
||||
}
|
||||
|
||||
result = applyBrandMistranslationFixes(enValue, result, locale)
|
||||
result = applyBrandMistranslationFixes(enValue, result, locale, key)
|
||||
result = applyPhraseFixes(enValue, result, locale)
|
||||
if (['zh', 'ja', 'ko'].includes(locale)) {
|
||||
result = applyCjkLatinTermSpacing(result, locale)
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ describe('locale-translation-policy', () => {
|
|||
localeValue: 'Jira の問題',
|
||||
locale: 'ja'
|
||||
})
|
||||
).toBe('Jira イシュー')
|
||||
).toBe('Jira Issue')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.mobile.MobileHero.668016be7a',
|
||||
|
|
@ -406,7 +406,7 @@ describe('locale-translation-policy', () => {
|
|||
localeValue: '選択した GitHub の課題またはプル リクエストをプレビューおよび編集します。',
|
||||
locale: 'ja'
|
||||
})
|
||||
).toBe('選択した GitHub イシューまたは PR をプレビュー・編集します。')
|
||||
).toBe('選択した GitHub Issue または PR をプレビュー・編集します。')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.GitHubItemDialog.a2495e4784',
|
||||
|
|
@ -422,7 +422,7 @@ describe('locale-translation-policy', () => {
|
|||
localeValue: '問題を表示する',
|
||||
locale: 'ja'
|
||||
})
|
||||
).toBe('イシューを表示')
|
||||
).toBe('Issue を表示')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.editor.EditorContent.e4b074749d',
|
||||
|
|
@ -439,7 +439,7 @@ describe('locale-translation-policy', () => {
|
|||
'GitHub CLI をインストールして、プル リクエスト、発行、チェックを有効にします。',
|
||||
locale: 'ja'
|
||||
})
|
||||
).toBe('GitHub CLI をインストールして PR、イシュー、チェックを有効にします。')
|
||||
).toBe('GitHub CLI をインストールして PR、Issue、チェックを有効にします。')
|
||||
expect(
|
||||
repairTranslatedValue({
|
||||
key: 'auto.components.mobile.MobilePage.e17393c6a3',
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ export const LOCALE_VALUE_OVERRIDES = {
|
|||
string: '文字列',
|
||||
Refreshing: '更新中',
|
||||
'Refreshing…': '更新中…',
|
||||
Issue: 'イシュー',
|
||||
Issue: 'Issue',
|
||||
'Privacy & Telemetry': 'プライバシーとテレメトリ',
|
||||
Experimental: '実験的機能',
|
||||
Advanced: '詳細設定',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue