summary refs log tree commit diff
path: root/nixos/modules/services/x11/xserver.nix
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2017-07-03 08:14:19 +0200
committeraszlig <aszlig@redmoonstudios.org>2017-07-03 08:29:20 +0200
commit69da1807f02daa776472893741c2f82eca8e838d (patch)
tree57a83bb0dca063a884c5b052be87b15daa2043cc /nixos/modules/services/x11/xserver.nix
parentd97cdfc591baf790ce5a9836e1503dfb0eb152e6 (diff)
downloadnixlib-69da1807f02daa776472893741c2f82eca8e838d.tar
nixlib-69da1807f02daa776472893741c2f82eca8e838d.tar.gz
nixlib-69da1807f02daa776472893741c2f82eca8e838d.tar.bz2
nixlib-69da1807f02daa776472893741c2f82eca8e838d.tar.lz
nixlib-69da1807f02daa776472893741c2f82eca8e838d.tar.xz
nixlib-69da1807f02daa776472893741c2f82eca8e838d.tar.zst
nixlib-69da1807f02daa776472893741c2f82eca8e838d.zip
nixos/xserver: Allow more than one keyboard layout
Regression introduced by 44c64fef16ed566786c8db276085b484c9d233f3.

The services.xserver.layout option allows to specify more than one
layout separated by comma, which the commit above didn't take into
account.

This is very similar to @lheckemann's pull request (#26984) but differs
in the following ways:

  * Print out the full list available layouts (as suggested by @0xABAB
    in [1]).
  * Loop over $layout using the default IFS (and thus no need for
    escaping ${cfg.layout}), because the layouts won't contain white
    spaces.
  * Re-do the error message, which now uses multiple echos instead of a
    heredoc, so the line is wrapped according to the viewers terminal
    width.

I've tested this with several good and bad layouts and also against the
keymap NixOS VM subtests.

[1]: https://github.com/NixOS/nixpkgs/pull/26984#discussion_r125146700

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Fixes: #26961
Closes: #26984
Diffstat (limited to 'nixos/modules/services/x11/xserver.nix')
-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 =