silent! on the colorscheme stops nvim erroring on a machine where PlugInstall has never run, but it does not give you gruvbox - it gives you the default theme without saying so. That is a safety net for the gap between checkout and install, not a fix. Setting up a machine now lists both steps: packages.sh for the system packages and PlugInstall for the ten nvim plugins. Also noted that firenvim reports "No config detected" for every browser on a headless host, which looks like a failure and is not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
176 lines
6.2 KiB
Markdown
176 lines
6.2 KiB
Markdown
# 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](https://developer.atlassian.com/blog/2016/02/best-way-to-store-dotfiles-git-bare-repo/):
|
|
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.zsh` — **theme 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>.zsh` — **the 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:
|
|
|
|
```sh
|
|
(( $+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
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
mkdir -p ~/.config/dotconfs && echo server > ~/.config/dotconfs/role
|
|
```
|
|
|
|
Then, by hand:
|
|
|
|
```sh
|
|
config config --local status.showUntrackedFiles no
|
|
config checkout master
|
|
```
|
|
|
|
Then install what the configuration files expect but do not carry:
|
|
|
|
```sh
|
|
.scripts/packages.sh install # system packages for the role
|
|
nvim --headless "+PlugInstall --sync" +qall # the nvim plugins
|
|
```
|
|
|
|
The nvim step matters more than it looks. gruvbox is a plugin, and until
|
|
`PlugInstall` has run, nvim comes up in the default theme. The `colorscheme`
|
|
line is wrapped in `silent!` so a fresh machine does not error before then —
|
|
that is a safety net for the gap, not a substitute for installing them.
|
|
|
|
On a headless machine `firenvim` will report "No config detected" for every
|
|
browser it looks for. That is expected and harmless.
|
|
|
|
> 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
|
|
|
|
```sh
|
|
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.
|