nixos/xserver: Allow more than one keyboard layout
Regression introduced by 44c64fef16.
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
This commit is contained in:
@@ -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
|
||||
}' "$xkbDir/rules/base.lst" | sort -u
|
||||
)"
|
||||
|
||||
cat >&2 <<-EOF
|
||||
layoutNotFound() {
|
||||
echo >&2
|
||||
echo "The following layouts and variants are available:" >&2
|
||||
echo >&2
|
||||
|
||||
The selected keyboard layout definition does not exist:
|
||||
# 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
|
||||
|
||||
$layout
|
||||
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 =
|
||||
|
||||
Reference in New Issue
Block a user