i18n: note about i18n.N_ usage and @inComptime() return msgid for i18n._

This commit is contained in:
Ēriks Remess
2026-03-19 18:00:58 +02:00
parent df23bef0e9
commit 1125fa26df
2 changed files with 36 additions and 0 deletions

View File

@@ -44,6 +44,30 @@ else
const label = gtk.Label.new(text);
```
If a string must be stored untranslated and only translated later, use
`i18n.N_` instead. This marks the string for extraction into the translation
template but returns the original msgid unchanged. A common use case is
compile-time or static metadata that is translated only when it is presented
to the user.
```zig
const i18n = @import("i18n.zig");
const Command = struct {
title: [:0]const u8,
};
const cmd = Command{
.title = i18n.N_("Reset Terminal"),
};
const label = gtk.Label.new(i18n._(cmd.title));
```
If `i18n._` is called at comptime, it returns the original msgid unchanged
while still marking the string for translation. For strings that are stored
untranslated and translated later, prefer `i18n.N_`.
All translatable strings are extracted into the _translation template file_,
located under `po/com.mitchellh.ghostty.pot`. **This file must stay in sync with
the list of translatable strings present in source code or Blueprints at all times.**

View File

@@ -62,8 +62,13 @@ pub fn initGlobalDomain() error{OutOfMemory}!void {
}
/// Translate a message for the Ghostty domain.
///
/// If this is called at comptime, the direct msgid is returned without
/// translation. This still allows the string to be marked for translation
/// while remaining usable in comptime contexts.
pub fn _(msgid: [*:0]const u8) [*:0]const u8 {
if (comptime !build_config.i18n) return msgid;
if (@inComptime()) return msgid;
return dgettext(build_config.bundle_id, msgid);
}
@@ -196,3 +201,10 @@ test "canonicalizeLocale darwin" {
// underscores. We should parse them out before calling this function.
try testing.expectEqualStrings("en_US.UTF_8", try canonicalizeLocale(&buf, "en_US.UTF-8"));
}
test "_ returns msgid at comptime" {
const testing = std.testing;
const msgid = comptime @"_"("Ghostty");
try testing.expectEqualStrings("Ghostty", std.mem.span(msgid));
}