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:
parent
d97cdfc591
commit
69da1807f0
@ -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 =
|
||||
|
Loading…
Reference in New Issue
Block a user