Skip to content

feat(i18n): localize composer surface (16 MessageIds)#2894

Closed
gordonlu wants to merge 1 commit into
Hmbown:mainfrom
gordonlu:feat/i18n-composer-clean
Closed

feat(i18n): localize composer surface (16 MessageIds)#2894
gordonlu wants to merge 1 commit into
Hmbown:mainfrom
gordonlu:feat/i18n-composer-clean

Conversation

@gordonlu

@gordonlu gordonlu commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Replace 16 hardcoded English strings in the composer panel with tr() calls across all 7 locales.

  • localization.rs: +16 MessageId variants + translations
  • widgets/mod.rs: wire tr() for title, placeholder, slash hints, submit dispositions, empty state, model/user-cmd descriptions; pin 3 existing tests to Locale::En; add Chinese English-leak test
  • qa_pty.rs: pin LANG=C for deterministic PTY assertions

3943 unit + 6 PTY tests pass, 0 warnings.

Greptile Summary

Localizes 16 previously hardcoded English strings in the composer panel across all 7 supported locales by adding new MessageId variants and wiring tr() calls in the widget and empty-state renderer. The PR also pins PTY tests to LANG=C, fixes a pre-existing bug where traditional_chinese silently served simplified-Chinese characters for ComposerPlaceholder (via the other => chinese_simplified(other)? catch-all), and adds a ZhHans no-English-leak test that covers both the slash-menu and empty-state paths.

  • All 16 new MessageId variants carry correct {count} / {name} / {workspace} / {version} placeholders in every locale, and the substitution call sites in widgets/mod.rs match.
  • The .claude/settings.json file (Claude Code IDE permissions) appears to have been committed inadvertently alongside the i18n work; it should be removed from source control and added to .gitignore.

Confidence Score: 5/5

The localization changes are safe to merge; the only non-localization file is an IDE settings file that should be excluded from the repo.

All format-string placeholder substitutions are consistent across locales and call sites, three pre-existing tests are correctly pinned to English, the new Chinese leak-detection test exercises both the slash-menu and empty-state paths, and PTY tests are pinned to LANG=C.

.claude/settings.json should be removed from source control rather than merged.

Important Files Changed

Filename Overview
.claude/settings.json New file granting Claude Code broad Bash permissions (rm *, source *, git checkout *, etc.); appears to have been committed alongside the i18n work and likely belongs in .gitignore rather than source control.
crates/tui/src/localization.rs Adds 16 new MessageId enum variants + translations in all 7 locales; traditional_chinese also gains an explicit ComposerPlaceholder entry (previously silently falling back to simplified Chinese characters via the other => chinese_simplified(other)? catch-all).
crates/tui/src/tui/widgets/mod.rs Replaces 16 hardcoded English strings with tr() calls; placeholder substitutions are correct; 3 existing tests pinned to Locale::En; new ZhHans leak-detection test exercises both the slash-menu branch and the empty-state path.
crates/tui/tests/qa_pty.rs Pins LANG=C in spawn_minimal and in the standalone skills_menu_shows_local_and_global_skills spawner, making all PTY assertions that check English strings deterministic.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["tr(locale, MessageId)"] --> B{locale}
    B -->|En| C["english(id)"]
    B -->|Vi / Ja / ZhHans / PtBr / Es419| D["locale_fn(id) Option"]
    B -->|ZhHant| E["traditional_chinese(id)"]
    E -->|explicit match| F["Traditional Chinese string"]
    E -->|other catch-all| G["chinese_simplified(id)?"]
    G -->|Some| H["Simplified Chinese fallback"]
    G -->|None| I["fallback_translation: english(id)"]
    D -->|Some| J["Translated string"]
    D -->|None| I
    C --> K["Widget renders tr() result"]
    F --> K
    H --> K
    J --> K
    I --> K
    K --> L["ComposerWidget / build_empty_state_lines"]
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (3): Last reviewed commit: "feat(i18n): localize composer surface (1..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks @gordonlu for taking the time to contribute.

This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS will be closed automatically.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant PR access by commenting /lgtm on a pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request localizes the Composer widget's UI strings (including titles, placeholders, empty state headers, and submit button hints) across multiple supported languages, and pins the locale to English in PTY tests to ensure deterministic assertions. A review comment suggests avoiding heap allocations in the hot rendering path by replacing the format! call used for padding with a static space span.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +576 to +582
Span::styled(
format!(
" {}",
self.app.tr(crate::localization::MessageId::ComposerSlashHintMove)
),
Style::default().fg(palette::TEXT_MUTED),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This format! call allocates a new String on every render frame. Since Renderable::render is called frequently (on every tick/input), we should avoid heap allocations in the hot path. We can achieve the same padding by adding a separate static space span Span::styled(" ", Style::default().fg(palette::TEXT_MUTED)) to the vector, which is completely zero-allocation.

                    Span::styled(" ", Style::default().fg(palette::TEXT_MUTED)),
                    Span::styled(
                        self.app.tr(crate::localization::MessageId::ComposerSlashHintMove),
                        Style::default().fg(palette::TEXT_MUTED),
                    ),

Comment thread crates/tui/src/localization.rs Outdated
Comment thread crates/tui/src/localization.rs Outdated
Comment thread crates/tui/src/localization.rs Outdated
Comment thread crates/tui/src/tui/widgets/mod.rs Outdated
@gordonlu gordonlu force-pushed the feat/i18n-composer-clean branch 2 times, most recently from 9d98bf1 to 0acba13 Compare June 8, 2026 06:04
@gordonlu gordonlu force-pushed the feat/i18n-composer-clean branch from 0acba13 to dfc6412 Compare June 8, 2026 06:04
@Hmbown

Hmbown commented Jun 10, 2026

Copy link
Copy Markdown
Owner

@gordonlu — same as the batch slices: conflicting after tonight's merges. Please rebase this composer slice after the main batch (#2892 → … → #2940) is through, so it only needs one pass.

@Hmbown Hmbown added v0.8.59 Targeting v0.8.59 localization Localization, i18n, and non-English language support ux User experience, interaction, or presentation polish labels Jun 11, 2026
@Hmbown Hmbown added this to the v0.8.59 milestone Jun 11, 2026
@Hmbown

Hmbown commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Closing this smaller i18n PR as superseded by the consolidation lane in #2239. #2239 covers the same surface area at broader Phase 1-4b scope and is the preferred v0.8.59 review target, though it still has its own outstanding review/fix work before merge.

@Hmbown Hmbown closed this Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

localization Localization, i18n, and non-English language support ux User experience, interaction, or presentation polish v0.8.59 Targeting v0.8.59

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants