diff --git a/hosts/nanuqsaurus.nix b/hosts/nanuqsaurus.nix index ac9f22e..78b2966 100644 --- a/hosts/nanuqsaurus.nix +++ b/hosts/nanuqsaurus.nix @@ -5,6 +5,7 @@ inputs.lix-module.nixosModules.lixFromNixpkgs ../modules/system/base.nix ../modules/system/packages.nix + ../modules/system/shell.nix ../modules/system/home-manager-skel.nix ../modules/desktop/gnome-minimal.nix ../modules/users/admin.nix diff --git a/modules/system/packages.nix b/modules/system/packages.nix index 02dacae..27d7c08 100644 --- a/modules/system/packages.nix +++ b/modules/system/packages.nix @@ -3,6 +3,7 @@ { # Baseline system tools available everywhere; users run Home Manager standalone. config.environment.systemPackages = lib.mkAfter [ + pkgs.git pkgs.ghostty pkgs.home-manager pkgs.just diff --git a/modules/system/shell.nix b/modules/system/shell.nix new file mode 100644 index 0000000..86e7b49 --- /dev/null +++ b/modules/system/shell.nix @@ -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 + }; + +} diff --git a/scripts/shell-init.sh b/scripts/shell-init.sh new file mode 100644 index 0000000..6fcac6f --- /dev/null +++ b/scripts/shell-init.sh @@ -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:-} 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 diff --git a/templates/home-home.nix b/templates/home-home.nix index a4d96e8..6b3b195 100644 --- a/templates/home-home.nix +++ b/templates/home-home.nix @@ -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; }