diff --git a/cmd/init.go b/cmd/init.go index b8c2595..598c75c 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -257,18 +257,32 @@ func initConstants() *constants { } // initI18n initializes a new i18n instance with the selected language map -// loaded from the filesystem. +// loaded from the filesystem. English is a loaded first as the default map +// and then the selected language is loaded on top of it so that if there are +// missing translations in it, the default English translations show up. func initI18n(lang string, fs stuffbin.FileSystem) *i18n.I18n { - b, err := fs.Read(fmt.Sprintf("/i18n/%s.json", lang)) + const def = "en" + + b, err := fs.Read(fmt.Sprintf("/i18n/%s.json", def)) if err != nil { - lo.Fatalf("error loading i18n language file: %v", err) + lo.Fatalf("error reading default i18n language file: %s: %v", def, err) } + // Initialize with the default language. i, err := i18n.New(b) if err != nil { lo.Fatalf("error unmarshalling i18n language: %v", err) } + // Load the selected language on top of it. + b, err = fs.Read(fmt.Sprintf("/i18n/%s.json", lang)) + if err != nil { + lo.Fatalf("error reading i18n language file: %v", err) + } + if err := i.Load(b); err != nil { + lo.Fatalf("error loading i18n language file: %v", err) + } + return i } diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go index 391301a..c22b4b5 100644 --- a/internal/i18n/i18n.go +++ b/internal/i18n/i18n.go @@ -43,6 +43,21 @@ func New(b []byte) (*I18n, error) { }, nil } +// Load loads a JSON language map into the instance overwriting +// existing keys that conflict. +func (i *I18n) Load(b []byte) error { + var l map[string]string + if err := json.Unmarshal(b, &l); err != nil { + return err + } + + for k, v := range l { + i.langMap[k] = v + } + + return nil +} + // Name returns the canonical name of the language. func (i *I18n) Name() string { return i.name