summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/x11/xserver.nix52
1 files changed, 36 insertions, 16 deletions
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix
index 504a6b79d577..bb9704fc26f0 100644
--- a/nixos/modules/services/x11/xserver.nix
+++ b/nixos/modules/services/x11/xserver.nix
@@ -651,29 +651,49 @@ in
     system.extraDependencies = singleton (pkgs.runCommand "xkb-layouts-exist" {
       inherit (cfg) layout xkbDir;
     } ''
-      if sed -n -e ':i /^! \(layout\|variant\) *$/ {
+      # We can use the default IFS here, because the layouts won't contain
+      # spaces or tabs and are ruled out by the sed expression below.
+      availableLayouts="$(
+        sed -n -e ':i /^! \(layout\|variant\) *$/ {
           # Loop through all of the layouts/variants until we hit another ! at
           # the start of the line or the line is empty ('t' branches only if
           # the last substitution was successful, so if the line is empty the
           # substition will fail).
           :l; n; /^!/bi; s/^ *\([^ ]\+\).*/\1/p; tl
-         }' "$xkbDir/rules/base.lst" | grep -qxF "$layout"
-      then
-        touch "$out"
-        exit 0
-      fi
-
-      cat >&2 <<-EOF
-
-      The selected keyboard layout definition does not exist:
-
-        $layout
+        }' "$xkbDir/rules/base.lst" | sort -u
+      )"
+
+      layoutNotFound() {
+        echo >&2
+        echo "The following layouts and variants are available:" >&2
+        echo >&2
+
+        # While an output width of 80 is more desirable for small terminals, we
+        # really don't know the amount of columns of the terminal from within
+        # the builder. The content in $availableLayouts however is pretty
+        # large, so let's opt for a larger width here, because it will print a
+        # smaller amount of lines on modern KMS/framebuffer terminals and won't
+        # lose information even in smaller terminals (it only will look a bit
+        # ugly).
+        echo "$availableLayouts" | ${pkgs.utillinux}/bin/column -c 150 >&2
+
+        echo >&2
+        echo "However, the keyboard layout definition in" \
+             "\`services.xserver.layout' contains the layout \`$1', which" \
+             "isn't a valid layout or variant." >&2
+        echo >&2
+        exit 1
+      }
 
-      Set \`services.xserver.layout' to the name of an existing keyboard
-      layout (check $xkbDir/rules/base.lst for options).
+      # Again, we don't need to take care of IFS, see the comment for
+      # $availableLayouts.
+      for l in ''${layout//,/ }; do
+        if ! echo "$availableLayouts" | grep -qxF "$l"; then
+          layoutNotFound "$l"
+        fi
+      done
 
-      EOF
-      exit 1
+      touch "$out"
     '');
 
     services.xserver.config =