feat: split zshrc into a stub and role-aware fragments

Load order is the substance of this change, and two attempts got it wrong in
the same way. oh-my-zsh consumes both the plugins array and the theme while it
is being sourced, so anything set afterwards is silently ignored. The plan had
plugins in the stub but the theme in the role file, which produced a shell
reporting ZSH_THEME=powerlevel10k while running without powerlevel10k at all -
132 of its functions missing and nobody any the wiser. Plugins and prompt are
now both resolved before oh-my-zsh, the latter in 05-prompt.zsh.

Portability is handled by asking whether a command exists rather than by
duplicating files per role. "alias ls='lsd'" turns ls into a broken command on
a machine without lsd, and the Mac is such a machine; the yay aliases and
helpers are gated the same way. That keeps one shared base instead of three
diverging copies.

The plan also guessed the plugin list as (git fzf). It is actually seven
entries, so five would have vanished - among them signal-keyring, which turned
out to be a local custom plugin present on this machine only. Naming it
elsewhere means an oh-my-zsh warning at every login, and its content is a
verbatim copy of the gnome-keyring block already in .zshrc, so it ran twice.
The inline block stays, in the desktop role; the plugin is dropped.

Dead code removed rather than carried over:
  - PYTHONPATH pointed at /usr/lib/python3.9/site-packages. Python here is
    3.14 and that directory does not exist.
  - XDG_SESSION_TYPE was forced to x11 and then tested for "wayland" six lines
    below, so that branch could never be taken. The variable belongs to the
    session; overriding it lies to everything that reads it.
  - drm() was defined twice, the first losing to the second on every start.
  - PATH carried ~/bin, ~/.scripts and /usr/X11R6/bin, none of which exist.
    Entries are added only if the directory is there.

Verified against the live configuration in an isolated ZDOTDIR: 277 aliases and
263 functions on both sides, none missing, and powerlevel10k loading for all
three roles with the intended colour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
thomas.kopp
2026-08-07 15:41:52 +02:00
co-authored by Claude Opus 5
parent 49357eced4
commit ce560c315d
8 changed files with 393 additions and 124 deletions
+53 -124
View File
@@ -1,134 +1,63 @@
# Path to your oh-my-zsh configuration.
ZSH=$HOME/.oh-my-zsh
# Stub only. Everything of substance lives in ~/.config/zsh/rc.d/.
#
# Load order, and why it is this one:
#
# 1. p10k instant prompt must be the first thing that runs
# 2. role needed before plugins, see below
# 3. plugins must be set before oh-my-zsh reads them
# 4. oh-my-zsh
# 5. rc.d/[1-4]*.zsh shared by every machine
# 6. rc.d/50-<role>.zsh exactly one of desktop/server/mobile
# 7. rc.d/90-local.zsh machine-local, never in the repository
#
# Step 3 is the reason the role is resolved so early: oh-my-zsh consumes the
# plugins array while sourcing, so nothing loaded afterwards can influence it.
# Set name of the theme to load.
# Look in ~/.oh-my-zsh/themes/
# Optionally, if you set this to "random", it'll load a random theme each
# time that oh-my-zsh is loaded.
ZSH_THEME="ys"
# Must stay at the top: this block may print, and anything above it that also
# prints breaks the instant prompt. Absent on machines without powerlevel10k,
# where the test simply fails and nothing happens.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# alias vi="vim"
export ZSH="$HOME/.oh-my-zsh"
# Set to this to use case-sensitive completion
# CASE_SENSITIVE="true"
# Defaults to desktop so a machine without the file still gets a working shell.
# Servers must have it in place before the first login, or shron comes up on
# the desktop profile - blue prompt on a production mail server.
ROLE=$(cat "$HOME/.config/dotconfs/role" 2>/dev/null || echo desktop)
export ROLE
# Comment this out to disable bi-weekly auto-update checks
# DISABLE_AUTO_UPDATE="true"
# One list for every machine, filtered by what is actually installed. A plugin
# named but not present makes oh-my-zsh complain on every single shell start,
# and the alternative - a separate list per role - means editing three files to
# add one plugin.
_want_plugins=(git archlinux colored-man-pages colorize zsh-interactive-cd fzf)
plugins=()
for _p in $_want_plugins; do
if [[ -d "$ZSH/plugins/$_p" || -d "${ZSH_CUSTOM:-$ZSH/custom}/plugins/$_p" ]]; then
plugins+=("$_p")
fi
done
unset _p _want_plugins
# Uncomment to change how many often would you like to wait before auto-updates occur? (in days)
# export UPDATE_ZSH_DAYS=13
zstyle ':omz:update' mode auto
# Uncomment following line if you want to disable colors in ls
# DISABLE_LS_COLORS="true"
# Also before oh-my-zsh: it loads the theme while sourcing, and powerlevel10k
# reads its settings when it loads. Putting either in the role file - which is
# sourced afterwards - leaves the value set and the theme unloaded.
[[ -r "$HOME/.config/zsh/rc.d/05-prompt.zsh" ]] && source "$HOME/.config/zsh/rc.d/05-prompt.zsh"
# Uncomment following line if you want to disable autosetting terminal title.
# DISABLE_AUTO_TITLE="true"
source "$ZSH/oh-my-zsh.sh"
# Uncomment following line if you want red dots to be displayed while waiting for completion
# COMPLETION_WAITING_DOTS="true"
# Example format: plugins=(rails git textmate ruby lighthouse)
#ALIASES
# vi starts vim
alias vi="nvim"
# update for archlinux
# in debian like oses you should change it to sudo apt update && sudo apt upgrade
# for nixos sudo nix-channel --update && sudo nixos rebuild-switch
alias update="yaourt -Syua --noconfirm"
#check directory sizes
alias ducks="du -cksh * | sort -rn | head"
# for backup in git
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
# (N) makes an empty directory a no-op instead of an error.
for _f in "$HOME"/.config/zsh/rc.d/[1-4]*.zsh(N); do
source "$_f"
done
unset _f
# bind page up and page down? can't remember but think this must be. :)
bindkey "\033[1~" beginning-of-line
bindkey "\033[4~" end-of-line
[[ -r "$HOME/.config/zsh/rc.d/50-$ROLE.zsh" ]] && source "$HOME/.config/zsh/rc.d/50-$ROLE.zsh"
#Add Plugins to oh my zsh
plugins=(git archlinux history-substring-search)
#include the oh my zsh config
source $ZSH/oh-my-zsh.sh
# Customize to your needs...
export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:$HOME/.scripts
export PYTHONPATH=/usr/lib/python3.9/site-packages
# if colors of ls don't work as expected the following line delete all colors from ls
# export LS_COLORS="rs=0:di=01;96:ln=04;01;35:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30; 43:ca=30;41:tw=30;42:$"
# Add dircolors plugin from:
# add it with: yaourt -S zsh-dircolors-solarized-git
# alternatively you can add it with: git clone --recursive git://github.com/joel-porquet/zsh-dircolors-solarized $ZSH_CUSTOM/plugins/zsh-dircolors-solarized
# and than add it to plugins line above (line 40)
# enable it with: setupsolarized
#source /usr/share/zsh/plugins/zsh-dircolors-solarized/zsh-dircolors-solarized.zsh
# function to detect ddos attacks
function detect-ddos {
sudo netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
}
# function to simple block suspicious IPs
# simply type ipt-block ipadress
function ipt-block {
sudo iptables -A INPUT -s $1 -j DROP
echo "permblocked $1"
}
function ipt-block_all_incoming {
# Set default chain policies
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# Accept on localhost
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow established sessions to receive traffic
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
}
#function to load actual IP Blocklist from openbl and ban them out
function update-blacklist {
CHAINLIST=$(sudo /sbin/iptables -nL | grep 'Chain block-traffic-from-openbl' | cut -d\ -f 2)
if [ -z $CHAINLIST ]; then
sudo /sbin/iptables -N block-traffic-from-openbl
sudo /sbin/iptables -A INPUT -j block-traffic-from-openbl
fi
BLACKLIST=$(/usr/bin/curl -fs http://www.openbl.org/lists/base_7days.txt.gz | gunzip | egrep "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1, 3}\.[0-9]{1,3}")
if [ $? -ne 0 ]; then
echo "Blacklist download failed."
exit
fi
sudo /sbin/iptables -F block-traffic-from-openbl
IPCOUNT=$(echo $BLACKLIST | tr ' ' '\n' | wc -l)
echo "Adding $IPCOUNT IPs to blacklist. - $(date)"
echo $BLACKLIST | tr ' ' '\n' | while read -r line ; do
case "$line" in \#*) continue ;; esac
sudo /sbin/iptables -A block-traffic-from-openbl -p tcp -s $line -j REJECT --reject-with tcp-reset
done
}
function inventarisierung {
NETZ=$(ip route | awk '/scope link/ {print $1}')
read "KUNDE?Bitte Kundenurl eingeben: "
sudo nmap -v -O -oG ~/cloud.tueit.de/Kunden/$KUNDE/$KUNDE.txt $NETZ
grep "OS:" ~/cloud.tueit.de/Kunden/$KUNDE/$KUNDE.txt | sed 's/Host: //' | sed 's/Ports.*OS://' | sed 's/Seq.*$//' | sed 's/(//' | sed 's/)//'
grep "OS:" ~/cloud.tueit.de/Kunden/$KUNDE/$KUNDE.txt | sed 's/Host: //' | sed 's/Ports.*OS://' | sed 's/Seq.*$//' | sed 's/(//' | sed 's/)//' | awk '{print "\"" $1 "\";\""$2"\";\"" $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 " " $10 " " $11 " " $12 " " $13 " " $14 "\""}' >~/cloud.tueit.de/Kunden/$KUNDE/$KUNDE.csv
}
# add some PERL Path variables
PATH="$HOME/perl5/bin${PATH+:}${PATH}"; export PATH;
PERL5LIB="$HOME/perl5/lib/perl5${PERL5LIB+:}${PERL5LIB}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="$HOME/perl5${PERL_LOCAL_LIB_ROOT+:}${PERL_LOCAL_LIB_ROOT}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"$HOME/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=$HOME/perl5"; export PERL_MM_OPT;
export TERM="xterm-256color"
source /home/templis/.config/broot/launcher/bash/br
# Last on purpose: this one can override anything above without the repository
# needing to know about it.
[[ -r "$HOME/.config/zsh/rc.d/90-local.zsh" ]] && source "$HOME/.config/zsh/rc.d/90-local.zsh"