thomas.koppandClaude Opus 5 6999f19b0a fix: resolve powerline's tmux bindings instead of pinning a Python version
tmux.conf sourced
  /usr/lib/python3.11/site-packages/powerline/bindings/tmux/powerline.conf
which puts a Python minor version in a path. It was already wrong before this
repository touched anything: beastix runs 3.14, so tmux has been printing that
error there for however long. shron never had the problem because its own
tmux.conf had the line commented out - until the checkout replaced that file
with this copy, and every session there started with the error.

Replacing a deliberately disabled setting with a broken one is the worse of the
two outcomes, and it is exactly what "every machine carries every file" costs
when a file is not actually machine-neutral.

The path now comes from the module itself, so it survives Python upgrades, and
each step exits quietly if something is missing. The Mac has neither powerline
nor tmux and gets nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 22:42:19 +02:00

dotconfs

Configuration for three machines out of one repository: an Arch desktop, an Arch server and a Mac. The role is decided when the shell starts, not when files are deployed.

The bare-repository technique is from an Atlassian post: a git directory in $HOME/.cfg with $HOME as its work tree, driven by an alias. No symlinks, no extra tooling.

Roles

Role Machine Prompt
desktop beastix — Arch, KDE powerlevel10k, blue
server shron — Arch, headless powerlevel10k, ASCII, red
mobile the Mac — macOS, Apple Silicon ys, green once p10k is there

Red on the server is a guard, not decoration. shron carries mail, web and cloud, and the prompt should answer "which machine is this" before the next command is typed.

The role lives in ~/.config/dotconfs/role, one word, and is not tracked — a shared copy would defeat the purpose. Write it before the first login. Without it the shell falls back to desktop.

Layout

.zshrc                        stub: role, then oh-my-zsh, then the fragments
.zprofile                     login shells only; Homebrew's shellenv
.config/zsh/rc.d/
  05-pre-omz.zsh              theme and plugins - must precede oh-my-zsh
  10-aliases.zsh              shared
  20-functions.zsh            shared
  30-path.zsh                 shared
  50-desktop.zsh              exactly one of these is sourced
  50-server.zsh
  50-mobile.zsh
  90-local.zsh                machine-local, never committed
.config/zsh/p10k-server.zsh   the server's prompt, ASCII and font-agnostic
packages/                     one plain list per platform and role
.scripts/packages.sh          check | install
.scripts/curate.sh            derive a package list from usage

Every machine checks out every file. A KDE configuration on the server is a few inert kilobytes and costs less than the machinery needed to avoid it.

Load order

It matters, and getting it wrong fails quietly:

  1. powerlevel10k instant prompt — must be first, it may print
  2. role
  3. 05-pre-omz.zshtheme and plugins, because oh-my-zsh consumes both while it is being sourced. Set afterwards, they are ignored: an early attempt reported ZSH_THEME=powerlevel10k from a shell running without it.
  4. oh-my-zsh
  5. 10- to 40- — shared
  6. 50-<role>.zshthe prompt colour, because ~/.p10k.zsh assigns POWERLEVEL9K_CONTEXT_BACKGROUND itself and is sourced in 30-path.zsh
  7. 90-local.zsh — last, so it can override anything

Theme before oh-my-zsh, colour after .p10k.zsh. Two constraints pulling in opposite directions.

Portability

Anything that depends on a command is guarded by whether that command exists, rather than duplicated per role:

(( $+commands[lsd] )) && alias ls='lsd'

Without the guard, alias ls='lsd' turns ls into a broken command on a machine without lsd. The Mac is such a machine.

Plugins are assembled per role and then filtered by what is installed. Naming a plugin that is absent produces an oh-my-zsh warning at every single login.

Packages

Lists are plain names, one per line — data, not code, so they port to home-manager and environment.systemPackages almost unchanged.

.scripts/packages.sh          what is missing, what is extra
.scripts/packages.sh install  install what is missing

It never removes anything. Extras are reported and left alone: on a server, individual packages carry mail and web services.

curate.sh derives a candidate list from four usage signals, because each one alone is blind to something — shell history sees no GUI application, KDE's activity database sees no chat client, autostart sees only what starts by itself, and flatpaks never appear in pacman -Qqe. On beastix that turned 512 explicit packages into 62.

Secrets

Credentials live beside the code that reads them and are never committed. The waybar mail module imports from mailsecrets.py; .gitignore covers that, private keys, .netrc, .pgpass, and .config/kdeconnect/, which holds the device certificate.

Machine-local overrides and anything sensitive belong in .config/zsh/rc.d/90-local.zsh, which is sourced last and never tracked.

config add -f still bypasses all of it. The ignore list guards against carelessness, not intent.

Setting up a new machine

curl -Ls https://ls.shron.de/dotconf | /bin/bash

The installer clones into $HOME/.cfg, defines the alias and moves anything in the way to .config-backup. Write the role file before the first login:

mkdir -p ~/.config/dotconfs && echo server > ~/.config/dotconfs/role

Then, by hand:

config config --local status.showUntrackedFiles no
config checkout master

Earlier revisions of this file used curl -Lks. The -k disables certificate verification against a host that has a valid certificate, removing precisely the protection that matters when piping a remote script into a shell. It is gone.

Day to day

config status
config add .zshrc
config commit -m "..."
config push

status.showUntrackedFiles=no keeps $HOME from drowning the output.

Servers pull over HTTPS rather than SSH: a machine that only consumes configuration has no business holding push credentials.

History

Everything before 2026-08-07 is on archive/2021-i3-sway. That tree described an i3/sway desktop that no longer exists — its display menu drove xrandr outputs the machine does not have — while the live files had moved on by years. master was rebuilt from the running configuration rather than merged with it.

S
Description
No description provided
Readme
243 KiB
Languages
Vim script 75%
Shell 25%