Add shell module and bootstrap fixes

This commit is contained in:
randogoth 2026-02-02 22:07:05 +02:00
parent 280f83488b
commit 879754cb8d
5 changed files with 202 additions and 1 deletions

View file

@ -5,6 +5,7 @@
inputs.lix-module.nixosModules.lixFromNixpkgs inputs.lix-module.nixosModules.lixFromNixpkgs
../modules/system/base.nix ../modules/system/base.nix
../modules/system/packages.nix ../modules/system/packages.nix
../modules/system/shell.nix
../modules/system/home-manager-skel.nix ../modules/system/home-manager-skel.nix
../modules/desktop/gnome-minimal.nix ../modules/desktop/gnome-minimal.nix
../modules/users/admin.nix ../modules/users/admin.nix

View file

@ -3,6 +3,7 @@
{ {
# Baseline system tools available everywhere; users run Home Manager standalone. # Baseline system tools available everywhere; users run Home Manager standalone.
config.environment.systemPackages = lib.mkAfter [ config.environment.systemPackages = lib.mkAfter [
pkgs.git
pkgs.ghostty pkgs.ghostty
pkgs.home-manager pkgs.home-manager
pkgs.just pkgs.just

39
modules/system/shell.nix Normal file
View file

@ -0,0 +1,39 @@
{ pkgs, ... }:
let
shellInitScript =
builtins.replaceStrings
[ "@ATUIN@" "@STARSHIP@" "@BASHPREEXEC@" ]
[
"${pkgs.atuin}/bin/atuin"
"${pkgs.starship}/bin/starship"
"${pkgs.bash-preexec}/share/bash/bash-preexec.sh"
]
(builtins.readFile ../../scripts/shell-init.sh);
in
{
environment.systemPackages = [
pkgs.atuin
pkgs.bat
pkgs.eza
pkgs.fzf
pkgs.starship
pkgs.ugrep
pkgs.zoxide
];
# Use Ghostty as the default terminal emulator.
environment.sessionVariables = {
TERMINAL = "${pkgs.ghostty}/bin/ghostty";
DEFAULT_TERMINAL = "${pkgs.ghostty}/bin/ghostty";
};
programs.bash = {
enable = true;
interactiveShellInit = shellInitScript;
loginShellInit = shellInitScript;
promptInit = ""; # avoid overriding Starship prompt
};
}

155
scripts/shell-init.sh Normal file
View file

@ -0,0 +1,155 @@
log_shell_init() {
printf '%s\n' "shell-init: $*" >>/tmp/shell-init.log 2>/dev/null
}
ensure_bash_preexec() {
# Load bash-preexec to wire preexec/precmd hooks for Atuin.
if [ -n "${BASH_VERSION:-}" ] && [ -z "${bash_preexec_imported:-}" ] && [ -r "@BASHPREEXEC@" ]; then
# shellcheck disable=SC1090
. "@BASHPREEXEC@"
log_shell_init "bash-preexec sourced"
fi
}
append_prompt_command() {
local cmd="$1"
case ";${PROMPT_COMMAND:-};" in
*";$cmd;"*) log_shell_init "PROMPT_COMMAND already has $cmd" ;;
"")
PROMPT_COMMAND="$cmd"
log_shell_init "PROMPT_COMMAND set to $cmd"
;;
*)
PROMPT_COMMAND="${PROMPT_COMMAND%;};$cmd"
log_shell_init "PROMPT_COMMAND appended $cmd -> ${PROMPT_COMMAND}"
;;
esac
}
# Consider shells with a TTY interactive even if PS1 is empty.
interactive=0
if [ -t 1 ]; then
interactive=1
elif [ -n "$PS1" ]; then
interactive=1
fi
# Ensure a sane TERM for prompt tools.
if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then
export TERM=xterm-256color
fi
log_shell_init "TERM=$TERM PS1=${PS1:-<empty>} SHELL=$SHELL interactive=$interactive"
# Ensure PS1 is set so Atuin/Starship init blocks run consistently.
if [ $interactive -eq 1 ] && [ -z "${PS1:-}" ]; then
PS1='\\s-\\v\\$ '
fi
# Load bash-preexec early (needed by Atuin).
if [ $interactive -eq 1 ]; then
ensure_bash_preexec
if command -v __bp_install >/dev/null 2>&1; then
__bp_install
fi
fi
# Prompt via Starship (manual init to avoid PROMPT_COMMAND being lost).
if [ $interactive -eq 1 ] && command -v @STARSHIP@ >/dev/null 2>&1; then
log_shell_init "starship init"
case "$SHELL" in
*/bash) eval "$(@STARSHIP@ init bash)" ;;
*/zsh) eval "$(@STARSHIP@ init zsh)" ;;
esac
append_prompt_command starship_precmd
else
log_shell_init "starship skipped (not interactive or missing)"
fi
# Enable Atuin history integration after Starship so preexec/precmd arrays keep Atuin.
if [ $interactive -eq 1 ] && command -v @ATUIN@ >/dev/null 2>&1; then
# Ensure session is established even if init script fails to export.
if [ -z "${ATUIN_SESSION:-}" ]; then
ATUIN_SESSION=$(@ATUIN@ uuid)
export ATUIN_SESSION
ATUIN_HISTORY_ID=""
fi
log_shell_init "atuin init"
case "$SHELL" in
*/bash) eval "$(@ATUIN@ init bash)" ;;
*/zsh) eval "$(@ATUIN@ init zsh)" ;;
esac
# Ensure Atuin hooks stay present.
if [ -n "${preexec_functions[*]:-}" ]; then
# Remove existing duplicates then prepend Atuin.
tmp=()
for f in "${preexec_functions[@]}"; do
[ "$f" = "__atuin_preexec" ] && continue
tmp+=("$f")
done
preexec_functions=(__atuin_preexec "${tmp[@]}")
unset tmp
else
preexec_functions=(__atuin_preexec)
fi
if [ -n "${precmd_functions[*]:-}" ]; then
tmp=()
for f in "${precmd_functions[@]}"; do
[ "$f" = "__atuin_precmd" ] && continue
tmp+=("$f")
done
precmd_functions=(__atuin_precmd "${tmp[@]}")
unset tmp
else
precmd_functions=(__atuin_precmd)
fi
else
log_shell_init "atuin skipped"
fi
# Directory jumping via zoxide.
if [ $interactive -eq 1 ] && command -v zoxide >/dev/null 2>&1; then
log_shell_init "zoxide init"
case "$SHELL" in
*/bash) eval "$(zoxide init bash)" ;;
*/zsh) eval "$(zoxide init zsh)" ;;
esac
else
log_shell_init "zoxide skipped"
fi
# Ensure zoxide hook stays in PROMPT_COMMAND even if starship overwrote it.
if [ $interactive -eq 1 ] && command -v __zoxide_hook >/dev/null 2>&1; then
append_prompt_command __zoxide_hook
fi
# Ensure bash-preexec precmd is present even if other init overwrote PROMPT_COMMAND.
if [ $interactive -eq 1 ] && command -v __bp_precmd_invoke_cmd >/dev/null 2>&1; then
append_prompt_command __bp_precmd_invoke_cmd
fi
if [ $interactive -eq 1 ] && command -v __bp_interactive_mode >/dev/null 2>&1; then
append_prompt_command __bp_interactive_mode
fi
# ls aliases via eza.
if command -v eza >/dev/null 2>&1; then
alias ll='eza -l --icons=auto --group-directories-first'
alias l.='eza -d .*'
alias ls='eza'
alias l1='eza -1'
fi
# grep aliases via ugrep.
if command -v ug >/dev/null 2>&1; then
alias grep='ug'
alias egrep='ug -E'
alias fgrep='ug -F'
alias xzgrep='ug -z'
alias xzegrep='ug -zE'
alias xzfgrep='ug -zF'
fi
# bat for cat.
if command -v bat >/dev/null 2>&1; then
alias cat='bat --style=plain --pager=never' 2>/dev/null
fi

View file

@ -70,7 +70,12 @@
''; '';
}; };
home.sessionVariables = { }; home.sessionVariables = {
# you can change the default terminal and editor here
TERMINAL = "${pkgs.ghostty}/bin/ghostty";
DEFAULT_TERMINAL = "${pkgs.ghostty}/bin/ghostty";
EDITOR = "${pkgs.micro}/bin/micro";
};
programs.home-manager.enable = true; programs.home-manager.enable = true;
} }