refactor(i18n): extract locale functions to localise.go

Move detectLanguage, SetFormality, Direction, IsRTL to dedicated file.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-01-30 15:02:20 +00:00
parent 0955847661
commit fe2fe7b425
2 changed files with 65 additions and 59 deletions

View file

@ -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.

65
pkg/i18n/localise.go Normal file
View file

@ -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 ""
}