{ pkgs, lib, ... }: with lib; { programs.bash = { enable = mkDefault true; enableCompletion = mkDefault true; shellAliases = { afk = "xset s activate dpms force off"; black-on-white = "echo -e '\\033]11;black\\007\\033]10;white\\007'"; c = "bat"; cl = "clear"; emacs = "emacsclient --create-frame"; grep = "grep --color"; j = "sudo journalctl -u"; jb = "sudo journalctl -b"; ju = "sudo journalctl --user -u"; l = "ls -alh"; ll = "ls -al"; ls = "ls --color=tty"; md-toc = "grep '^#\\+' --color"; mem = "ps -e -orss=,user=,args= | sort -b -k1,1n"; mem-top = "smem --sort rss --autosize"; mpl = "mplayer"; n = "networkctl"; nf = "sudo nft list ruleset | less"; nix-du-svg = "nix-du | dot -Tsvg >nix-du.svg"; nixos-clean = "sudo nix-collect-garbage -d"; nixos-history = "sudo nix-env --list-generations --profile /nix/var/nix/profiles/system"; nixos-rollback = "sudo nixos-rebuild switch --rollback"; nt = "networkctl status"; pass-gen = "tr -d -C A-Za-z0-9_- </dev/urandom | head -c"; r = "reset"; rot13 = "tr A-Za-z N-ZA-Mn-za-m"; rot135 = "tr A-Za-z0-9 N-ZA-Mn-za-m5-90-4"; rsync = "rsync --no-inc-recursive --info=progress2 --inplace --partial"; s = "sudo systemctl"; sr = "sudo systemctl restart"; st = "sudo systemctl status"; t = "tmux"; t0 = "tmux new -t 0"; t1 = "tmux new -t 1"; t2 = "tmux new -t 2"; theme-black-on-white = "echo -e '\\033]10;black\\007\\033]11;white\\007'"; theme-white-on-black = "echo -e '\\033]10;white\\007\\033]11;black\\007'"; u = "systemctl --user"; ur = "systemctl --user restart"; ut = "systemctl --user status"; w = "watch --color --differences"; w1 = "watch --color --differences --interval 1"; w10 = "watch --color --differences --interval 10"; w5 = "watch --color --differences --interval 5"; watch = "watch --color --differences"; z = "zfs"; ze = "sudo zpool export"; zfs-umount = "zfs-unmount"; zi = "sudo zpool import"; zl = "zfs list"; zlb = "zfs list -t bookmarks"; zls = "zfs list -t snap"; zm = "zfs-mount"; zp = "sudo zpool"; zs = "zpool status"; zs5 = "w5 zpool status"; zu = "zfs-unmount"; }; historyControl = [ "erasedups" "ignorespace" ]; historyIgnore = [ "torify" "mpv" ]; historySize = 42000; sessionVariables = { PS1 = ''\[\033[1;32m\]\[\e]0;\u@\h: \w\a\]\W\[\033[0m\] \$(e=\$?; if [ \$e != 0 ]; then echo '\[\e[0;91m\]'\$e'\[\e[0m\]'; fi)\$ ''; # More throughput than chacha20-poly1305@openssh.com # on hardware with AES acceleration. RSYNC_RSH = "ssh -c aes128-gcm@openssh.com,chacha20-poly1305@openssh.com"; }; initExtra = '' # Alias completion . ${pkgs.complete-alias}/bin/complete_alias complete -F _complete_alias "''${!BASH_ALIASES[@]}" shopt -s globstar shopt -s histappend shopt -s histreedit shopt -s histverify # Disable ctrl-s/ctrl-q flow control stty -ixon ffmpeg-audio () { for i in "$@"; do ffmpeg -i "$i" -vn -map 0:a -acodec copy "''${i%.*}".audio-only.mkv done } ffmpeg-opus () { for i in "$@"; do ffmpeg -i "$i" -vn -map 0:a -c:a libopus -b:a 64k -application voip "''${i%.*}".opus done } opusenc-voice () { find "$@" -depth -type f -print0 | sort -n -z | xargs -0 -P "$(lscpu --online -p | grep -v "#" | wc -l)" -I {} bash -c ' test -e "''${0%.*}".opus || nice -n 19 ffmpeg -y -i "$0" -map 0:a -b:a 32k -application voip "''${0%.*}".opus ' {} \; } ibm-fan () { if [ $# -gt 0 ] then sudo tee /proc/acpi/ibm/fan <<<"level $1" else grep '^\(level\|speed\):' /proc/acpi/ibm/fan fi acpi -t } mkcd () { mkdir -p "$1" && cd "$1" } mkpass () { tr -d -C 'A-Za-z0-9' </dev/urandom | head -c 25 | xclip } smartctl-tbw () { device=''${1:-/dev/sda} sudo smartctl -A $device | { awk ' $0 ~ /Power_On_Hours/ { poh=$10; printf "%s / %d hours / %d days / %.2f years\n", $2, $10, $10 / 24, $10 / 24 / 365.25 } $0 ~ /Total_LBAs_Written/ { lbas = $10; bytes = $10 * 512; mb = bytes / 1024^2; gb = bytes / 1024^3; tb = bytes / 1024^4; printf "%s / %s / %d mb / %.1f gb / %.3f tb\n", $2, $10, mb, gb, tb printf "mean writes per hour / %.2f", mb/poh } $0 ~ /Airflow_Temperature_Cel/ { print $2 " / " $10} $0 ~ /Wear_Leveling_Count/ { printf "%s / %d (%% health)\n", $2, int($4) } $0 ~ /Percentage Used:/ { printf "Percentage_Used / %d\n", int($3) } '; echo; } | sed -e 's:/:@:' | sed -e "s\$^\$$device @ \$" | column -ts@ } stress-mem() { fac="$1"; stress-ng --vm 1 --vm-keep --vm-bytes $(awk "/MemAvailable/{ printf \"%d\n\", \$2 * $fac; }" </proc/meminfo)k; } sysenter() { srv="$1"; shift; nsenter -a -t "$(systemctl show --property MainPID --value "$srv")" "$@"; } systrace() { srv="$1"; shift; strace -f -p "$(systemctl show --property MainPID --value "$srv")" "$@"; } swaplist () { lastpid= swap=0 sudo grep -H '^Swap:' /proc/*/smaps 2>/dev/null | while IFS=: read -r file x size x do pid=''${file#/proc/} pid=''${pid%/smaps} size=''${size% kB} size=''${size##* } if test "$pid" = "$lastpid" then swap=$(( swap + size )) else if test "$swap" -gt 0 then printf "%u pid=%u cmd=%s\n" "$swap" "$lastpid" "$(tr '\000' ' ' </proc/"$lastpid"/cmdline)" fi if test "$pid" = self then break else lastpid=$pid swap=$size fi fi done | sort -nk1,1 } # Recursively mount not-mounted dataset, # loading their keys if needed. zfs-mount () { ( set -e for d in $(zfs list -rH -o name "$@"); do mountpoint /mnt/"$d" 2>/dev/null || sudo zfs mount -l "$d" done ) } # Recursively unmount dataset, # unloading their keys. zfs-unmount () { sudo zfs unmount -u "$@"; } # Create bookmarks for all the snapshots of the given datasets. # Bookmarks are only useful on source datasets # But syncoid --create-bookmark only creates # a bookmark for the latest snapshot, # possibly leaving the *_daily or *_monthly snapshots without a bookmark. zfs-fix-bookmarks () { local d local - set -x for d in "$@"; do for s in $(zfs list -Hrpt snapshot -o name "$d"); do zfs bookmark "$s" "''${s//@/#}" done done } # Restore the inheritance of encryptionroot, # usually broken by zfs send --raw. # Note that it needs to decrypt the datasets. zfs-fix-encryptionroot () { local d zfs load-key "$1" for d in $(zfs list -rHo name "$1" | tail -n +2); do echo >&2 "$d" test "$(zfs get -Ho value encryptionroot $d)" = "$1" || zfs change-key -li "$d" done } # Recursively remove all the snapshots of given datasets zfs-destroy-snapshots () { local d for d in "$@"; do zfs list -t snapshot -rHo name "$d" | xargs --no-run-if-empty -L1 zfs destroy done } ''; profileExtra = '' ''; }; programs.direnv.enableBashIntegration = true; #programs.broot.enableBashIntegration = true; programs.readline = { enable = mkDefault true; includeSystemConfig = true; bindings = { # Up/Down "\\e[A" = "history-search-backward"; "\\e[B" = "history-search-forward"; "\\eOA" = "history-search-backward"; "\\eOB" = "history-search-forward"; # Ctrl-Left/Ctrl-Right "\\e[1;5C" = "forward-word"; "\\e[1;5D" = "backward-word"; "\\e[5C" = "forward-word"; "\\e[5D" = "backward-word"; "\\e\\e[C" = "forward-word"; "\\e\\e[D" = "backward-word"; # Home/End "\\e[1~" = "beginning-of-line"; "\\e[4~" = "end-of-line"; # Delete/Insert "\\e[3~" = "delete-char"; "\\e[2~" = "quoted-insert"; # For non RH/Debian xterm, can't hurt for RH/Debian xterm "\\eOF" = "end-of-line"; "\\eOH" = "beginning-of-line"; # For freebsd console "\\e[F" = "end-of-line"; "\\e[H" = "beginning-of-line"; # $if term=rxvt "\\e[7~" = "beginning-of-line"; "\\e[8~" = "end-of-line"; "\\eOc" = "forward-word"; "\\eOd" = "backward-word"; # $endif }; variables = { # Be 8 bit clean. input-meta = mkDefault true; output-meta = mkDefault true; colored-completion-prefix = mkDefault true; colored-stats = mkDefault true; # Note that this may cause completion text blink in some terminals (e.g. xterm). echo-control-characters = mkDefault true; mark-symlinked-directories = mkDefault true; menu-complete-display-prefix = mkDefault true; show-all-if-ambiguous = mkDefault true; show-all-if-unmodified = mkDefault true; visible-stats = mkDefault false; # Append char to indicate type enable-bracketed-paste = mkDefault true; }; }; }