diff --git a/dot_bash_profile.tmpl b/dot_bash_profile.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..18ed5737815a44f8d37da5bff6098d941caed7aa --- /dev/null +++ b/dot_bash_profile.tmpl @@ -0,0 +1,11 @@ +# ~/.bash_profile: executed by bash(1) for login shells. +# This file is managed by chezmoi. Modifications may be overwritten. +# The actual configuration is in $XDG_CONFIG_HOME/bash/profile + +# Source the real profile from XDG location +if [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/bash/profile" ]]; then + source "${XDG_CONFIG_HOME:-$HOME/.config}/bash/profile" +fi + +# Minimal additions that must stay in .bash_profile +complete -C /usr/bin/mcli mcli 2>/dev/null || true diff --git a/dot_bashrc.tmpl b/dot_bashrc.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..73ca3e00a22f1ed315926d3dc7b574d6e22c838b --- /dev/null +++ b/dot_bashrc.tmpl @@ -0,0 +1,8 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# This file is managed by chezmoi. Modifications may be overwritten. +# The actual configuration is in $XDG_CONFIG_HOME/bash/bashrc + +# Source the real bashrc from XDG location +if [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/bash/bashrc" ]]; then + source "${XDG_CONFIG_HOME:-$HOME/.config}/bash/bashrc" +fi diff --git a/dot_config/bash/bashrc.tmpl b/dot_config/bash/bashrc.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..1adf4c608fcc8cf3d6cd4f578bf58f88b684b18a --- /dev/null +++ b/dot_config/bash/bashrc.tmpl @@ -0,0 +1,255 @@ +# ============================================================================ +# Environment Variables +# ============================================================================ + +# XDG Base Directories +export XDG_DATA_HOME="$HOME/.local/share" +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_STATE_HOME="$HOME/.local/state" +export XDG_CACHE_HOME="$HOME/.cache" +export XDG_BIN_HOME="$HOME/.local/bin" +export XDG_BIN_DIR="$XDG_BIN_HOME" + +# Moving dotfiles around +export WINEPREFIX="$XDG_DATA_HOME/wine" +export WORKON_HOME="$XDG_DATA_HOME/virtualenvs" +export SQLITE_HISTORY="$XDG_CACHE_HOME/sqlite_history" +export BUNDLE_USER_CONFIG="$XDG_CONFIG_HOME/bundle" +export BUNDLE_USER_CACHE="$XDG_CACHE_HOME/bundle" +export BUNDLE_USER_PLUGIN="$XDG_DATA_HOME/bundle" +export NUGET_PACKAGES="$XDG_CACHE_HOME/NuGetPackages" +export DVDCSS_CACHE="$XDG_DATA_HOME/dvdcss" +export KDEHOME="$XDG_CONFIG_HOME/kde" +export GOPATH="$XDG_DATA_HOME/go" +export ZIM_HOME="$XDG_CONFIG_HOME/.zim" +export GHCUP_USE_XDG_DIRS="ishouldjustbeabletoexportthisnotsetit" +export NODE_PATH="$XDG_DATA_HOME/npm-packages/lib/node_modules" +export CARGO_HOME="$XDG_DATA_HOME/cargo" +export ASDF_DATA_DIR="$XDG_DATA_HOME/asdf" + +# pi coding agent +export PI_CODING_AGENT_DIR="$XDG_CONFIG_HOME/pi" + +# Android SDK +export ANDROID_HOME="$XDG_DATA_HOME/Android" +export ANDROID_SDK_ROOT="$ANDROID_HOME" + +# ============================================================================ +# PATH Configuration +# ============================================================================ + +# Prepend paths in reverse order (last becomes first in PATH) +path_prepend() { + case ":$PATH:" in + *":$1:"*) :;; # already in PATH + *) PATH="$1${PATH:+:$PATH}" ;; + esac +} + +# XDG_BIN_HOME takes highest priority +path_prepend "$XDG_BIN_HOME" +path_prepend "$XDG_CACHE_HOME/.bun/bin" +path_prepend "$HOME/.radicle/bin" +path_prepend "$XDG_DATA_HOME/cargo/bin" +path_prepend "$GOPATH/bin" +path_prepend "$XDG_CONFIG_HOME/emacs/bin" +path_prepend "/usr/local/go/bin" +path_prepend "/usr/lib/kf5" +path_prepend "/usr/lib/kf6" + +# Android SDK paths +path_prepend "$ANDROID_HOME/emulator" +path_prepend "$ANDROID_HOME/platform-tools" +path_prepend "$ANDROID_HOME/cmdline-tools/latest/bin" + +# Guix +export GUIX_LOCPATH="$HOME/.guix-profile/lib/locale" +export GUIX_PROFILE="$HOME/.guix-profile" +path_prepend "$GUIX_PROFILE/bin" + +# ============================================================================ +# Preferences and Tools +# ============================================================================ + +export BAT_THEME="ansi" +export DFT_BACKGROUND="light" +{{ if eq .chezmoi.hostname "sidhe" }} +export EDITOR="zed --wait" +{{ else }} +export EDITOR="zeditor --wait" +{{ end }} +export VISUAL="$EDITOR" +export MANPAGER="nvim +Man!" +export COLUMNS=80 +export MANWIDTH=80 +export RIPGREP_CONFIG_PATH="$HOME/.config/ripgreprc" +export RANGER_LOAD_DEFAULT_RC=false + +# Disable Python keyring +export PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring" + +# mise +if command -v mise &> /dev/null; then + eval "$(mise activate bash)" +fi + +# secrets (fnox) +if [[ -f "$XDG_CONFIG_HOME/fnox/age.txt" ]]; then + export FNOX_AGE_KEY=$(grep "AGE-SECRET-KEY" "$XDG_CONFIG_HOME/fnox/age.txt") + if command -v fnox &> /dev/null; then + eval "$(mise exec fnox@latest -- fnox activate bash 2>/dev/null || true)" + fi +fi + +# ============================================================================ +# History Configuration +# ============================================================================ + +# Don't put duplicate lines or lines starting with space in the history +HISTCONTROL=ignoreboth + +# Append to the history file, don't overwrite it +shopt -s histappend + +# History size +HISTSIZE=10000 +HISTFILESIZE=20000 + +# Save history to XDG location +export HISTFILE="$XDG_STATE_HOME/bash/history" +mkdir -p "$(dirname "$HISTFILE")" + +# ============================================================================ +# Shell Options +# ============================================================================ + +# Check window size after each command and update LINES/COLUMNS +shopt -s checkwinsize + +# Enable ** globstar (if available) +shopt -s globstar 2>/dev/null + +# Enable programmable completion +if ! shopt -oq posix; then + if [[ -f /usr/share/bash-completion/bash_completion ]]; then + source /usr/share/bash-completion/bash_completion + elif [[ -f /etc/bash_completion ]]; then + source /etc/bash_completion + fi +fi + +# ============================================================================ +# Aliases +# ============================================================================ + +{{ if ne .chezmoi.hostname "sidhe" }} +alias zed="zeditor" +{{ end }} + +alias wget="wget --hsts-file=\"$XDG_DATA_HOME/wget-hsts\"" +alias svn="svn --config-dir $XDG_CONFIG_HOME/subversion" +alias ts="tailscale" +alias datetime="date +%Y-%m-%d_%H%M%S_%Z" +alias clip="xclip -selection clipboard" +alias send="rsync -amzzP" +alias bat="bat -n --tabs 2" +alias erase="shred -vzfun 32" +alias dl="yt-dlp --write-sub --write-auto-sub --sub-lang en --sub-format srt/best --convert-subs srt --embed-subs -o '%(upload_date)s %(title)s.%(ext)s'" +alias us="unsilence -t 15 -as 1.25" +alias sxiv="sxiv -p" +alias c="chezmoi" +alias t="tuios" +alias ls="lsd" +alias soft="ssh git.secluded.site" +alias g="git" + +# Modern replacements +alias ll='ls -la' +alias la='ls -a' + +# ============================================================================ +# Functions +# ============================================================================ + +# cheat.sh integration +cht() { + if [[ $# -eq 0 ]]; then + echo "Usage: cht or cht /" + return 1 + fi + curl -s "cheat.sh/$*" +} + +# ============================================================================ +# Tool Integrations +# ============================================================================ + +# Starship prompt +if command -v starship &> /dev/null; then + eval "$(starship init bash)" +fi + +# Atuin history +if command -v atuin &> /dev/null; then + eval "$(atuin init bash --disable-up-arrow)" +fi + +# Completions (if available) +for cmd in lune tuios crush lx; do + if command -v "$cmd" &> /dev/null; then + eval "$("$cmd" completion bash 2>/dev/null || true)" + fi +done + +# ============================================================================ +# SSH Agent Management +# ============================================================================ + +if [[ -z "${SSH_AUTH_SOCK:-}" ]]; then + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" +fi + +if ! ssh-add -l &>/dev/null; then + eval "$(ssh-agent -a "$SSH_AUTH_SOCK" 2>/dev/null)" > /dev/null + echo "Spawned new ssh-agent. PID: $SSH_AGENT_PID" +fi + +{{ if eq .chezmoi.username "exedev" }} +# ============================================================================ +# exe.dev Hints (only for exedev user) +# ============================================================================ + +_exe_url() { + local fqdn prefix suffix + fqdn=$(hostname -f 2>/dev/null || hostname) + if [[ "$fqdn" == *.* ]]; then + prefix=${fqdn%%.*} + suffix=${fqdn#*.} + echo "https://${prefix}.${1}.${suffix}/" + else + echo "https://${fqdn}.${1}.exe.xyz/" + fi +} + +_exe_hints=( + $'Read exe.dev docs at https://exe.dev/docs' + "Shelley, our coding agent, is running at $(_exe_url shelley)" + $'Docker is installed and works; try "docker run --rm alpine:latest echo hello world"' + "If you run an http webserver on port 4444, you can access it securely at https://$(hostname -f 2>/dev/null || hostname):4444" + $'ssh into exe.dev to manage the HTTP proxy and sharing for this VM' + "There is a web-based terminal at $(_exe_url xterm)" +) +unset -f _exe_url + +_exe_hint_index=$((RANDOM % ${#_exe_hints[@]})) + +echo "" +echo "You are on $(hostname -f 2>/dev/null || hostname). The disk is persistent. You have 'sudo'." +echo "" +echo 'For support and documentation, "ssh exe.dev" or visit https://exe.dev/' +echo "" +printf '%s\n' "${_exe_hints[$_exe_hint_index]}" +echo "" + +unset _exe_hints _exe_hint_index +{{ end }} diff --git a/dot_config/bash/profile.tmpl b/dot_config/bash/profile.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..d7eecc06c9795baf67309c3d3b4117a25967fe5f --- /dev/null +++ b/dot_config/bash/profile.tmpl @@ -0,0 +1,4 @@ +# Source bashrc (login shells don't do this automatically) +if [[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/bash/bashrc" ]]; then + source "${XDG_CONFIG_HOME:-$HOME/.config}/bash/bashrc" +fi