1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 aggregatedLocales =
9 (builtins.map
10 (l: (lib.replaceStrings [ "utf8" "utf-8" "UTF8" ] [ "UTF-8" "UTF-8" "UTF-8" ] l) + "/UTF-8")
11 (
12 [ config.i18n.defaultLocale ]
13 ++ (lib.optionals (builtins.isList config.i18n.extraLocales) config.i18n.extraLocales)
14 ++ (lib.attrValues (lib.filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
15 )
16 )
17 ++ (lib.optional (builtins.isString config.i18n.extraLocales) config.i18n.extraLocales);
18in
19{
20 ###### interface
21
22 options = {
23
24 i18n = {
25 glibcLocales = lib.mkOption {
26 type = lib.types.path;
27 default = pkgs.glibcLocales.override {
28 allLocales = lib.any (x: x == "all") config.i18n.supportedLocales;
29 locales = config.i18n.supportedLocales;
30 };
31 defaultText = lib.literalExpression ''
32 pkgs.glibcLocales.override {
33 allLocales = lib.any (x: x == "all") config.i18n.supportedLocales;
34 locales = config.i18n.supportedLocales;
35 }
36 '';
37 example = lib.literalExpression "pkgs.glibcLocales";
38 description = ''
39 Customized pkg.glibcLocales package.
40
41 Changing this option can disable handling of i18n.defaultLocale
42 and supportedLocale.
43 '';
44 };
45
46 defaultLocale = lib.mkOption {
47 type = lib.types.str;
48 default = "en_US.UTF-8";
49 example = "nl_NL.UTF-8";
50 description = ''
51 The default locale. It determines the language for program
52 messages, the format for dates and times, sort order, and so on.
53 It also determines the character set, such as UTF-8.
54 '';
55 };
56
57 extraLocales = lib.mkOption {
58 type = lib.types.either (lib.types.listOf lib.types.str) (lib.types.enum [ "all" ]);
59 default = [ ];
60 example = [ "nl_NL.UTF-8" ];
61 description = ''
62 Additional locales that the system should support, besides the ones
63 configured with {option}`i18n.defaultLocale` and
64 {option}`i18n.extraLocaleSettings`.
65 Set this to `"all"` to install all available locales.
66 '';
67 };
68
69 extraLocaleSettings = lib.mkOption {
70 type = lib.types.attrsOf lib.types.str;
71 default = { };
72 example = {
73 LC_MESSAGES = "en_US.UTF-8";
74 LC_TIME = "de_DE.UTF-8";
75 };
76 description = ''
77 A set of additional system-wide locale settings other than
78 `LANG` which can be configured with
79 {option}`i18n.defaultLocale`.
80 '';
81 };
82
83 supportedLocales = lib.mkOption {
84 type = lib.types.listOf lib.types.str;
85 visible = false;
86 default = lib.unique (
87 [
88 "C.UTF-8/UTF-8"
89 "en_US.UTF-8/UTF-8"
90 ]
91 ++ aggregatedLocales
92 );
93 example = [
94 "en_US.UTF-8/UTF-8"
95 "nl_NL.UTF-8/UTF-8"
96 "nl_NL/ISO-8859-1"
97 ];
98 description = ''
99 List of locales that the system should support. The value
100 `"all"` means that all locales supported by
101 Glibc will be installed. A full list of supported locales
102 can be found at <https://sourceware.org/git/?p=glibc.git;a=blob;f=localedata/SUPPORTED>.
103 '';
104 };
105
106 };
107
108 };
109
110 ###### implementation
111
112 config = {
113 warnings =
114 lib.optional
115 (
116 !(
117 (lib.subtractLists config.i18n.supportedLocales aggregatedLocales) == [ ]
118 || lib.any (x: x == "all") config.i18n.supportedLocales
119 )
120 )
121 ''
122 `i18n.supportedLocales` is deprecated in favor of `i18n.extraLocales`,
123 and it seems you are using `i18n.supportedLocales` and forgot to
124 include some locales specified in `i18n.defaultLocale`,
125 `i18n.extraLocales` or `i18n.extraLocaleSettings`.
126
127 If you're trying to install additional locales not specified in
128 `i18n.defaultLocale` or `i18n.extraLocaleSettings`, consider adding
129 only those locales to `i18n.extraLocales`.
130 '';
131
132 environment.systemPackages =
133 # We increase the priority a little, so that plain glibc in systemPackages can't win.
134 lib.optional (config.i18n.supportedLocales != [ ]) (lib.setPrio (-1) config.i18n.glibcLocales);
135
136 environment.sessionVariables = {
137 LANG = config.i18n.defaultLocale;
138 LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
139 } // config.i18n.extraLocaleSettings;
140
141 systemd.globalEnvironment = lib.mkIf (config.i18n.supportedLocales != [ ]) {
142 LOCALE_ARCHIVE = "${config.i18n.glibcLocales}/lib/locale/locale-archive";
143 };
144
145 # ‘/etc/locale.conf’ is used by systemd.
146 environment.etc."locale.conf".source = pkgs.writeText "locale.conf" ''
147 LANG=${config.i18n.defaultLocale}
148 ${lib.concatStringsSep "\n" (
149 lib.mapAttrsToList (n: v: "${n}=${v}") config.i18n.extraLocaleSettings
150 )}
151 '';
152
153 };
154}