diff --git a/.chezmoiignore.tmpl b/.chezmoiignore.tmpl index 65e45a5..391adc4 100644 --- a/.chezmoiignore.tmpl +++ b/.chezmoiignore.tmpl @@ -1,4 +1,5 @@ **/*.bak +README.md {{ if ne .chezmoi.hostname "flow" -}} .config/pulsemeeter {{- end }} diff --git a/README.md b/README.md new file mode 100644 index 0000000..54c9632 --- /dev/null +++ b/README.md @@ -0,0 +1,123 @@ +# dotfiles + +Personal dotfiles managed with [chezmoi](https://www.chezmoi.io/). + +Per-host configuration is handled with Go templates, so the same repo works on +every machine: + +| Host | Type | Notes | +|---|---|---| +| `flow` | desktop, personal | DP-1/DP-2 outputs, pulsemeeter, teams-for-linux | +| `gata` | desktop, work | two monitors, teams-for-linux | +| `framework13pro` | laptop, personal | eDP-1, touchpad, brightness keys | + +## Setup on a new machine + +```sh +sudo pacman -S chezmoi +chezmoi init --apply git@gitea.itspm.cc:pmcc/dotfiles +``` + +For hosts not yet covered (`flow`, `gata`), fill in the `# TODO` output lines: + +1. `swaymsg -t get_outputs | jq -r '.[].name'` +2. Edit `dot_config/sway/config.d/outputs.conf.tmpl` in the source, replacing the TODOs with real `output` lines (one per monitor, e.g. `output DP-1 mode 2560x1440@144Hz position 0 0`) +3. For gata, also replace the `// TODO` in `dot_config/waybar/config.jsonc.tmpl` with the correct monitor names +4. `chezmoi apply` then `swaymsg reload` + +## Cheatsheet + +| Command | What it does | +|---|---| +| `chezmoi edit ` | Edit the source state of a managed file (`chezmoi edit ~/.tmux.conf`) | +| `chezmoi edit --apply ` | Edit and apply in one step | +| `chezmoi add ` | Add a new file to dotfiles | +| `chezmoi re-add ` | Pull a live-edited file back into source | +| `chezmoi status` | Show pending changes (target vs source) | +| `chezmoi diff` | Preview what `apply` would change | +| `chezmoi apply -v` | Apply source → home | +| `chezmoi update` | Pull latest from gitea + apply | +| `chezmoi cd` | Jump to the source dir (`~/.local/share/chezmoi`) — commit/push from here | +| `chezmoi managed` / `chezmoi unmanaged` | List managed / unmanaged files | +| `chezmoi data` | Show template variables (e.g. `hosttype` for this host) | +| `chezmoi doctor` | Diagnose setup issues | + +Typical workflow: `chezmoi cd` → edit files → `git commit && git push` → on +other machines `chezmoi update`. + +## How per-host config works + +- `.chezmoi.toml.tmpl` maps the hostname to a `hosttype` data variable + (`laptop` / `desktop`) in `~/.config/chezmoi/chezmoi.toml` +- `dot_config/sway/config.d/*.tmpl` branch per hostname (outputs) or per + `hosttype` (inputs, binds) — deployed into `~/.config/sway/config.d/`, which + the base sway config includes via `include ~/.config/sway/config.d/*` +- `dot_config/waybar/config.jsonc.tmpl` renders the bar array per host; shared + bar/module definitions live in `.chezmoitemplates/` +- `.chezmoiignore.tmpl` scopes app configs to specific hosts: + pulsemeeter on `flow` only, teams-for-linux on desktop hosts + +## Template syntax + +Files ending in `.tmpl` are rendered with Go's `text/template` and deployed +under the same name minus the suffix (`config.jsonc.tmpl` → `config.jsonc`). +`{{ ... }}` delimits template actions; anything outside them is literal text. + +**Variables** — built-ins like `.chezmoi.hostname`, `.chezmoi.os`, and custom +ones from `[data]` in the generated config, here `.hosttype`: + +``` +{{ if eq .hosttype "laptop" }} +bindsym XF86MonBrightnessUp exec brightnessctl s +5% +{{ end }} +``` + +**Conditionals**: + +``` +{{ if eq .chezmoi.hostname "flow" }}...{{ else if eq .hosttype "laptop" }}...{{ end }} +``` + +**Whitespace control** — `{{-` trims whitespace before the action, `-}}` +trims after; this keeps conditionals from leaving stray blank lines in the +output. + +**Shared fragments** — `.chezmoitemplates/` files are included with +`{{ template "name" . }}`, optionally passing data: + +``` +{{ template "bar-primary" (dict "out" "eDP-1" "ws" (list "1" "2" "3" "4")) }} +``` + +**Previewing** without touching your home dir: + +```sh +# render one template for a specific host +chezmoi execute-template --init --override-data '{"chezmoi":{"hostname":"flow"}}' < file.tmpl + +# render the whole source state into a scratch dir +mkdir -p /tmp/test && chezmoi --source ~/.local/share/chezmoi apply --destination /tmp/test +``` + +Note: templates that render to empty output are not deployed — that's why +`flow`/`gata` have no `inputs.conf`/`binds.conf`. + +## What each chezmoi file does + +| Source file | Deploys as | Purpose | +|---|---|---| +| `dot_zshrc`, `dot_tmux.conf` | `~/.zshrc`, `~/.tmux.conf` | plain dotfiles (`dot_` → leading dot) | +| `dot_config/…` | `~/.config/…` | config tree | +| `executable_install.sh` | `install.sh` with `+x` | scripts — executability needs the `executable_` prefix; chezmoi ignores the source file's own mode | +| `*.tmpl` | same name, rendered | per-host / templated content | +| `.chezmoi.toml.tmpl` | `~/.config/chezmoi/chezmoi.toml` (at `chezmoi init`) | defines `[data]` variables like `hosttype` | +| `.chezmoiignore.tmpl` | *(never deployed)* | patterns matched against **target** paths to skip, template-capable | +| `.chezmoitemplates/*` | *(never deployed)* | shared template fragments, included with `{{ template "name" . }}` | + +## Package lists + +`~/.config/dotfiles/install.sh` installs the packages from the rendered +`packages.txt` (official repos) and `aur-packages.txt` (AUR). The lists are +templates too, so host-specific software (pulsemeeter, teams-for-linux) is only +installed where it's used. The lists intentionally only cover software with +configs in this repo — the base OS install is assumed to already exist.