From fe2fe7b42569abdb7dedc8666ddbc5a809e3032f Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 30 Jan 2026 15:02:20 +0000 Subject: [PATCH] refactor(i18n): extract locale functions to localise.go Move detectLanguage, SetFormality, Direction, IsRTL to dedicated file. Co-Authored-By: Claude Opus 4.5 --- pkg/i18n/i18n.go | 59 ---------------------------------------- pkg/i18n/localise.go | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 59 deletions(-) create mode 100644 pkg/i18n/localise.go diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go index 267d8afe..52707a6b 100644 --- a/pkg/i18n/i18n.go +++ b/pkg/i18n/i18n.go @@ -26,12 +26,9 @@ package i18n import ( "bytes" "embed" - "os" "strings" "sync" "text/template" - - "golang.org/x/text/language" ) //go:embed locales/*.json @@ -80,28 +77,6 @@ func (m Message) ForCategory(cat PluralCategory) string { // --- Global convenience functions --- -// SetFormality sets the default formality level on the default service. -// -// SetFormality(FormalityFormal) // Use formal address (Sie, vous) -func SetFormality(f Formality) { - if svc := Default(); svc != nil { - svc.SetFormality(f) - } -} - -// Direction returns the text direction for the current language. -func Direction() TextDirection { - if svc := Default(); svc != nil { - return svc.Direction() - } - return DirLTR -} - -// IsRTL returns true if the current language uses right-to-left text. -func IsRTL() bool { - return Direction() == DirRTL -} - // T translates a message using the default service. // For semantic intents (core.* namespace), pass a Subject as the first argument. // @@ -173,40 +148,6 @@ func _(messageID string, args ...any) string { return messageID } -func detectLanguage(supported []language.Tag) string { - langEnv := os.Getenv("LANG") - if langEnv == "" { - langEnv = os.Getenv("LC_ALL") - if langEnv == "" { - langEnv = os.Getenv("LC_MESSAGES") - } - } - if langEnv == "" { - return "" - } - - // Parse LANG format: en_GB.UTF-8 -> en-GB - baseLang := strings.Split(langEnv, ".")[0] - baseLang = strings.ReplaceAll(baseLang, "_", "-") - - parsedLang, err := language.Parse(baseLang) - if err != nil { - return "" - } - - if len(supported) == 0 { - return "" - } - - matcher := language.NewMatcher(supported) - bestMatch, _, confidence := matcher.Match(parsedLang) - - if confidence >= language.Low { - return bestMatch.String() - } - return "" -} - // --- Template helpers --- // templateCache stores compiled templates for reuse. diff --git a/pkg/i18n/localise.go b/pkg/i18n/localise.go new file mode 100644 index 00000000..7a3d7556 --- /dev/null +++ b/pkg/i18n/localise.go @@ -0,0 +1,65 @@ +// Package i18n provides internationalization for the CLI. +package i18n + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// SetFormality sets the default formality level on the default service. +// +// SetFormality(FormalityFormal) // Use formal address (Sie, vous) +func SetFormality(f Formality) { + if svc := Default(); svc != nil { + svc.SetFormality(f) + } +} + +// Direction returns the text direction for the current language. +func Direction() TextDirection { + if svc := Default(); svc != nil { + return svc.Direction() + } + return DirLTR +} + +// IsRTL returns true if the current language uses right-to-left text. +func IsRTL() bool { + return Direction() == DirRTL +} + +func detectLanguage(supported []language.Tag) string { + langEnv := os.Getenv("LANG") + if langEnv == "" { + langEnv = os.Getenv("LC_ALL") + if langEnv == "" { + langEnv = os.Getenv("LC_MESSAGES") + } + } + if langEnv == "" { + return "" + } + + // Parse LANG format: en_GB.UTF-8 -> en-GB + baseLang := strings.Split(langEnv, ".")[0] + baseLang = strings.ReplaceAll(baseLang, "_", "-") + + parsedLang, err := language.Parse(baseLang) + if err != nil { + return "" + } + + if len(supported) == 0 { + return "" + } + + matcher := language.NewMatcher(supported) + bestMatch, _, confidence := matcher.Match(parsedLang) + + if confidence >= language.Low { + return bestMatch.String() + } + return "" +}