diff --git a/pkgs/nomarchy-install/nomarchy-install.sh b/pkgs/nomarchy-install/nomarchy-install.sh index 8ea40b6..ee7ac37 100644 --- a/pkgs/nomarchy-install/nomarchy-install.sh +++ b/pkgs/nomarchy-install/nomarchy-install.sh @@ -16,6 +16,7 @@ # NOMARCHY_UNATTENDED=1 NOMARCHY_DISK=/dev/vda NOMARCHY_USERNAME=me \ # NOMARCHY_PASSWORD=secret [NOMARCHY_HOSTNAME=nomarchy] \ # [NOMARCHY_TIMEZONE=UTC] [NOMARCHY_LUKS_PASSPHRASE=...] \ +# [NOMARCHY_LOCALE=en_US.UTF-8] [NOMARCHY_KB_LAYOUT=us] [NOMARCHY_KB_VARIANT=] \ # [NOMARCHY_SWAP_GB=N (default: RAM size; 0 = none)] \ # [NOMARCHY_HW="auto"|"none"|"mod1 mod2"] [NOMARCHY_FINISH=none|reboot|poweroff] # nomarchy-install @@ -150,6 +151,9 @@ if [[ "$UNATTENDED" == "1" ]]; then PASSWORD="${NOMARCHY_PASSWORD:?}" HOSTNAME_="${NOMARCHY_HOSTNAME:-nomarchy}" TIMEZONE="${NOMARCHY_TIMEZONE:-UTC}" + LOCALE="${NOMARCHY_LOCALE:-en_US.UTF-8}" + KB_LAYOUT="${NOMARCHY_KB_LAYOUT:-us}" + KB_VARIANT="${NOMARCHY_KB_VARIANT:-}" else while true; do USERNAME=$(gum input --placeholder "username (lowercase, e.g. ada)") @@ -169,6 +173,26 @@ else warn "Invalid hostname." done TIMEZONE=$(timedatectl list-timezones | gum filter --placeholder "timezone (type to search)" || echo UTC) + # Curated UTF-8 locales: the live system only generates en_US, so + # `locale -a` can't enumerate what the TARGET could use. + LOCALE=$(printf '%s\n' \ + en_US en_GB de_DE fr_FR es_ES es_MX pt_PT pt_BR it_IT nl_NL \ + pl_PL ru_RU uk_UA cs_CZ sk_SK sv_SE nb_NO da_DK fi_FI tr_TR \ + el_GR hu_HU ro_RO bg_BG hr_HR sl_SI lt_LT lv_LV et_EE ja_JP \ + ko_KR zh_CN zh_TW ar_EG he_IL hi_IN th_TH vi_VN id_ID \ + | sed 's/$/.UTF-8/' \ + | gum filter --placeholder "language / locale (type to search)" \ + || echo en_US.UTF-8) + KB_LAYOUT=$(localectl list-x11-keymap-layouts 2>/dev/null \ + | gum filter --placeholder "keyboard layout (type to search)" \ + || echo us) + KB_VARIANT="" + if [[ "$KB_LAYOUT" != "us" ]] || gum confirm --default=No "Pick a keyboard variant (intl, nodeadkeys, …)?"; then + KB_VARIANT=$( { echo "(none)"; localectl list-x11-keymap-variants "$KB_LAYOUT" 2>/dev/null; } \ + | gum filter --placeholder "variant for $KB_LAYOUT (pick '(none)' for the default)" \ + || echo "(none)") + [[ "$KB_VARIANT" == "(none)" ]] && KB_VARIANT="" + fi fi [[ "$USERNAME" =~ ^[a-z_][a-z0-9_-]*$ ]] || fail "Invalid username '$USERNAME'." [[ -f "/usr/share/zoneinfo/$TIMEZONE" || -e "/etc/zoneinfo/$TIMEZONE" ]] \ @@ -177,6 +201,7 @@ fi HASHED_PASSWORD=$(printf '%s' "$PASSWORD" | mkpasswd -m sha-512 -s) unset PASSWORD info "User: $USERNAME @ $HOSTNAME_ ($TIMEZONE)" +info "Locale: $LOCALE · keyboard: $KB_LAYOUT${KB_VARIANT:+ ($KB_VARIANT)}" # ─── Hardware profile ─────────────────────────────────────────────────── section "Hardware detection" @@ -320,9 +345,35 @@ nixos-generate-config --root /mnt mv /mnt/etc/nixos/hardware-configuration.nix "$FLAKE_DIR/" rm -rf /mnt/etc/nixos -cp "$SHARE/template/home.nix" "$FLAKE_DIR/" cp "$SHARE/template/theme-state.json" "$FLAKE_DIR/" +# home.nix is generated (not copied from the template) so the chosen +# keyboard layout reaches the Hyprland session — standalone HM cannot +# read system.nix. +cat > "$FLAKE_DIR/home.nix" < "$FLAKE_DIR/system.nix" < /mnt/root/nomarchy-hm-activate.sh < /var/log/nomarchy-hm-preactivate.log 2>&1 export PATH=/run/current-system/sw/bin:\$PATH -out=\$(nix --extra-experimental-features "nix-command flakes" \ - build --no-link --print-out-paths \ - --option substituters "" \ - "path:/home/$USERNAME/.nomarchy#homeConfigurations.$USERNAME.activationPackage") +# Normally pre-built in the live env and copied over; the in-chroot +# build (default substituters — the live-side build already proved the +# no-network case) is a last-resort fallback. +out="$hm_out" +if [ -z "\$out" ]; then + out=\$(nix --extra-experimental-features "nix-command flakes" \ + build --no-link --print-out-paths \ + "path:/home/$USERNAME/.nomarchy#homeConfigurations.$USERNAME.activationPackage") +fi install -d -o "$USERNAME" -g users /nix/var/nix/profiles/per-user/$USERNAME install -d -o "$USERNAME" -g users /nix/var/nix/gcroots/per-user/$USERNAME # activate's profile ops need store access; as the user that means a diff --git a/templates/downstream/home.nix b/templates/downstream/home.nix index 29b4ba1..9420a2c 100644 --- a/templates/downstream/home.nix +++ b/templates/downstream/home.nix @@ -9,6 +9,9 @@ # nomarchy.terminal = "kitty"; # swap the default terminal # nomarchy.waybar.enable = false; # bring your own bar # nomarchy.stylix.enable = false; # opt out of GTK/Qt theming + # nomarchy.keyboard.layout = "de"; # session keyboard (pair with + # # xkb + console.useXkbConfig in + # # system.nix for tty/LUKS) home.packages = with pkgs; [ # firefox diff --git a/tools/test-install.sh b/tools/test-install.sh index 48cd1a2..37db568 100755 --- a/tools/test-install.sh +++ b/tools/test-install.sh @@ -47,8 +47,8 @@ if df --output=fstype "$TARGET_DIR" | tail -1 | grep -q tmpfs; then exit 1 fi -OVMF="" -for c in /run/current-system/sw/share/qemu/edk2-x86_64-code.fd \ +OVMF="${NOMARCHY_OVMF:-}" +[ -n "$OVMF" ] || for c in /run/current-system/sw/share/qemu/edk2-x86_64-code.fd \ /run/current-system/sw/share/OVMF/OVMF_CODE.fd \ /usr/share/OVMF/OVMF_CODE.fd; do [ -f "$c" ] && { OVMF="$c"; break; }