feat: keymap/locale + form factor in installer; nm-applet visible by default
- Installer prompts for keyboard layout (with optional variant) and locale
via curated short list + Other… fallback into the full localectl list;
applies to the live session immediately (loadkeys + hyprctl) so the
rest of the install types correctly. Generated system.nix emits
console.keyMap, i18n.defaultLocale, and services.xserver.xkb.{layout,
variant}.
- New nomarchy.{system,}.formFactor enum (laptop|desktop, default laptop).
Installer auto-detects via /sys/class/power_supply/BAT* and lets the
user flip the answer. Waybar drops the battery widget on desktop;
battery-monitor service is gated on the same option.
- Lift waybar tray out of the collapsed group/tray-expander in the default
theme so nm-applet's icon is visible without expanding the drawer.
- Live ISOs (TTY + graphical) get baseline mkDefault keyMap/locale so the
installer's runtime override always wins.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -33,11 +33,26 @@ USERNAME=""
|
||||
LUKS_PASSWORD=""
|
||||
USER_PASSWORD=""
|
||||
TIMEZONE="UTC"
|
||||
KEYMAP_LAYOUT=""
|
||||
KEYMAP_VARIANT=""
|
||||
LOCALE=""
|
||||
FORM_FACTOR=""
|
||||
HARDWARE_MODULES=""
|
||||
NOMARCHY_HW_OPTS=""
|
||||
# "" = not yet answered; "true"/"false" set by configure_impermanence.
|
||||
ENABLE_IMPERMANENCE=""
|
||||
|
||||
# Curated short lists for the keymap/locale prompts. "Other…" drops the user
|
||||
# into the full `localectl` list via gum filter.
|
||||
COMMON_KEYMAPS=(
|
||||
us de fr gb es it pt br se no fi dk nl pl ru ua ch jp kr cn ar
|
||||
)
|
||||
COMMON_LOCALES=(
|
||||
en_US.UTF-8 en_GB.UTF-8 de_DE.UTF-8 fr_FR.UTF-8 es_ES.UTF-8
|
||||
it_IT.UTF-8 pt_BR.UTF-8 pt_PT.UTF-8 nl_NL.UTF-8 sv_SE.UTF-8
|
||||
ja_JP.UTF-8 zh_CN.UTF-8 ko_KR.UTF-8
|
||||
)
|
||||
|
||||
# CLI flags
|
||||
DRY_RUN="false"
|
||||
RESUME="false"
|
||||
@@ -79,6 +94,7 @@ parse_args() {
|
||||
save_state() {
|
||||
declare -p \
|
||||
TARGET_DRIVE USERNAME HOSTNAME TIMEZONE \
|
||||
KEYMAP_LAYOUT KEYMAP_VARIANT LOCALE FORM_FACTOR \
|
||||
ENABLE_IMPERMANENCE HARDWARE_MODULES NOMARCHY_HW_OPTS NOMARCHY_REV \
|
||||
> "$STATE_FILE"
|
||||
}
|
||||
@@ -320,6 +336,67 @@ configure_user() {
|
||||
save_state
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# STEP 5a: KEYBOARD & LANGUAGE
|
||||
# ============================================================================
|
||||
|
||||
# Curated short list first ("Other…" drops into the full localectl list).
|
||||
# Applied IMMEDIATELY to the running session so the rest of the install types
|
||||
# correctly — TTY uses loadkeys, Hyprland uses hyprctl. Both best-effort.
|
||||
select_keymap_locale() {
|
||||
section "Keyboard & Language"
|
||||
|
||||
if [[ -z "$KEYMAP_LAYOUT" ]]; then
|
||||
local choice
|
||||
choice=$(printf '%s\n' "${COMMON_KEYMAPS[@]}" "Other…" \
|
||||
| nrun gum choose --header "Keyboard layout")
|
||||
if [[ "$choice" == "Other…" ]]; then
|
||||
KEYMAP_LAYOUT=$(localectl list-x11-keymap-layouts 2>/dev/null \
|
||||
| nrun gum filter --placeholder "Search keyboard layout…")
|
||||
else
|
||||
KEYMAP_LAYOUT="$choice"
|
||||
fi
|
||||
[[ -z "$KEYMAP_LAYOUT" ]] && KEYMAP_LAYOUT="us"
|
||||
fi
|
||||
success "Keyboard layout: $KEYMAP_LAYOUT"
|
||||
|
||||
# Variant — optional. Only prompt if the layout actually has variants.
|
||||
if [[ -z "$KEYMAP_VARIANT" ]]; then
|
||||
local variants
|
||||
variants=$(localectl list-x11-keymap-variants "$KEYMAP_LAYOUT" 2>/dev/null || true)
|
||||
if [[ -n "$variants" ]]; then
|
||||
local v
|
||||
v=$(printf '(none)\n%s\n' "$variants" \
|
||||
| nrun gum filter --placeholder "Variant (optional)" --value "(none)")
|
||||
[[ "$v" == "(none)" || -z "$v" ]] || KEYMAP_VARIANT="$v"
|
||||
fi
|
||||
fi
|
||||
[[ -n "$KEYMAP_VARIANT" ]] && success "Variant: $KEYMAP_VARIANT" || success "Variant: (default)"
|
||||
|
||||
# Apply to the live session, best-effort.
|
||||
loadkeys "$KEYMAP_LAYOUT" 2>/dev/null || true
|
||||
if [[ -n "${WAYLAND_DISPLAY:-}" ]] && command -v hyprctl >/dev/null 2>&1; then
|
||||
hyprctl keyword input:kb_layout "$KEYMAP_LAYOUT" >/dev/null 2>&1 || true
|
||||
hyprctl keyword input:kb_variant "$KEYMAP_VARIANT" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if [[ -z "$LOCALE" ]]; then
|
||||
local choice
|
||||
choice=$(printf '%s\n' "${COMMON_LOCALES[@]}" "Other…" \
|
||||
| nrun gum choose --header "Language / locale")
|
||||
if [[ "$choice" == "Other…" ]]; then
|
||||
LOCALE=$(localectl list-locales 2>/dev/null \
|
||||
| nrun gum filter --placeholder "Search locale…")
|
||||
else
|
||||
LOCALE="$choice"
|
||||
fi
|
||||
[[ -z "$LOCALE" ]] && LOCALE="en_US.UTF-8"
|
||||
fi
|
||||
success "Locale: $LOCALE"
|
||||
|
||||
save_state
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# STEP 5: TIMEZONE
|
||||
# ============================================================================
|
||||
@@ -497,6 +574,36 @@ _select_hardware_manual() {
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# STEP 6b: FORM FACTOR (LAPTOP / DESKTOP)
|
||||
# ============================================================================
|
||||
|
||||
# Auto-detects via /sys/class/power_supply/BAT* — same signal hardware-db.sh
|
||||
# uses to pick common-pc-laptop vs common-pc. The user can flip the answer
|
||||
# (e.g. a desktop with a UPS that exposes a BAT*, or a laptop that doesn't).
|
||||
confirm_form_factor() {
|
||||
section "Form Factor"
|
||||
|
||||
if [[ -n "$FORM_FACTOR" ]]; then
|
||||
success "Resumed: $FORM_FACTOR"
|
||||
return
|
||||
fi
|
||||
|
||||
local default="desktop"
|
||||
if compgen -G "/sys/class/power_supply/BAT*" >/dev/null; then
|
||||
default="laptop"
|
||||
fi
|
||||
info "Auto-detected: $default"
|
||||
|
||||
if nrun gum confirm "Treat this machine as a $default?"; then
|
||||
FORM_FACTOR="$default"
|
||||
else
|
||||
FORM_FACTOR=$([[ "$default" == "laptop" ]] && echo desktop || echo laptop)
|
||||
fi
|
||||
success "Form factor: $FORM_FACTOR"
|
||||
save_state
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# STEP 7: IMPERMANENCE (OPTIONAL)
|
||||
# ============================================================================
|
||||
@@ -533,7 +640,10 @@ review_configuration() {
|
||||
echo " Drive: $TARGET_DRIVE (BTRFS + LUKS2)"
|
||||
echo " Hostname: $HOSTNAME"
|
||||
echo " Username: $USERNAME"
|
||||
echo " Keymap: $KEYMAP_LAYOUT${KEYMAP_VARIANT:+ ($KEYMAP_VARIANT)}"
|
||||
echo " Locale: $LOCALE"
|
||||
echo " Timezone: $TIMEZONE"
|
||||
echo " Form factor: $FORM_FACTOR"
|
||||
echo " Impermanence: $ENABLE_IMPERMANENCE"
|
||||
echo " Nomarchy rev: ${NOMARCHY_REV:-main (unpinned)}"
|
||||
echo ""
|
||||
@@ -821,12 +931,29 @@ EOF
|
||||
|
||||
# system.nix — curated system-level options. Uncomment what you want and
|
||||
# run \`sudo nixos-rebuild switch --flake /etc/nixos#$HOSTNAME\` to apply.
|
||||
# XKB variant is optional — only emit when the user picked one.
|
||||
local xkb_variant_line=""
|
||||
if [[ -n "$KEYMAP_VARIANT" ]]; then
|
||||
xkb_variant_line=" variant = \"$KEYMAP_VARIANT\";"
|
||||
fi
|
||||
|
||||
cat > /mnt/etc/nixos/system.nix << EOF
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
networking.hostName = "$HOSTNAME";
|
||||
time.timeZone = "$TIMEZONE";
|
||||
|
||||
# Keyboard & language — set by the installer.
|
||||
console.keyMap = "$KEYMAP_LAYOUT";
|
||||
i18n.defaultLocale = "$LOCALE";
|
||||
services.xserver.xkb = {
|
||||
layout = "$KEYMAP_LAYOUT";
|
||||
$xkb_variant_line
|
||||
};
|
||||
|
||||
# Physical form factor — gates UI affordances (battery widget, etc).
|
||||
nomarchy.system.formFactor = "$FORM_FACTOR";
|
||||
|
||||
$impermanence_opt
|
||||
|
||||
# Compressed RAM swap. Near-free memory headroom on small machines and
|
||||
@@ -914,15 +1041,22 @@ EOF
|
||||
|
||||
# home.nix — curated app menu. Uncomment what you want and run
|
||||
# `nomarchy-env-update` to apply.
|
||||
cat > /mnt/etc/nixos/home.nix << 'EOF'
|
||||
#
|
||||
# NB: not heredoc-quoted — we expand $FORM_FACTOR. Any literal `$` or
|
||||
# backtick in the body must be escaped.
|
||||
cat > /mnt/etc/nixos/home.nix << EOF
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# Physical form factor — mirrors nomarchy.system.formFactor in system.nix.
|
||||
# Gates UI affordances like the waybar battery widget.
|
||||
nomarchy.formFactor = "$FORM_FACTOR";
|
||||
|
||||
# User-level packages (Home Manager).
|
||||
#
|
||||
# Nomarchy already ships a minimal desktop (firefox, thunar, mpv, imv, mako,
|
||||
# hyprlock, swww, wl-clipboard, grim, slurp, rofi-wayland, etc.). The list
|
||||
# below is a menu of extras — uncomment what you want and run
|
||||
# `nomarchy-env-update`.
|
||||
# \`nomarchy-env-update\`.
|
||||
home.packages = with pkgs; [
|
||||
# --- Enabled by default ---
|
||||
btop # Resource monitor (TUI)
|
||||
@@ -989,8 +1123,8 @@ EOF
|
||||
# --- Optional Nomarchy app modules ---
|
||||
|
||||
# opencode AI coding CLI integration (deploys ~/.config/opencode/opencode.json).
|
||||
# The `opencode` package itself is not installed automatically — add it to
|
||||
# `home.packages` above if you want it on PATH.
|
||||
# The \`opencode\` package itself is not installed automatically — add it to
|
||||
# \`home.packages\` above if you want it on PATH.
|
||||
# nomarchy.apps.opencode.enable = true;
|
||||
|
||||
# Extra Home Manager modules go here (program configs, services, etc.).
|
||||
@@ -1041,8 +1175,10 @@ main() {
|
||||
select_disk
|
||||
get_luks_passphrase
|
||||
configure_user
|
||||
select_keymap_locale
|
||||
select_timezone
|
||||
select_hardware
|
||||
confirm_form_factor
|
||||
configure_impermanence
|
||||
review_configuration
|
||||
execute_installation
|
||||
|
||||
Reference in New Issue
Block a user