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:
parent
0955847661
commit
fe2fe7b425
2 changed files with 65 additions and 59 deletions
|
|
@ -26,12 +26,9 @@ package i18n
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"embed"
|
"embed"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed locales/*.json
|
//go:embed locales/*.json
|
||||||
|
|
@ -80,28 +77,6 @@ func (m Message) ForCategory(cat PluralCategory) string {
|
||||||
|
|
||||||
// --- Global convenience functions ---
|
// --- 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.
|
// T translates a message using the default service.
|
||||||
// For semantic intents (core.* namespace), pass a Subject as the first argument.
|
// For semantic intents (core.* namespace), pass a Subject as the first argument.
|
||||||
//
|
//
|
||||||
|
|
@ -173,40 +148,6 @@ func _(messageID string, args ...any) string {
|
||||||
return messageID
|
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 ---
|
// --- Template helpers ---
|
||||||
|
|
||||||
// templateCache stores compiled templates for reuse.
|
// templateCache stores compiled templates for reuse.
|
||||||
|
|
|
||||||
65
pkg/i18n/localise.go
Normal file
65
pkg/i18n/localise.go
Normal 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 ""
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue