Personal, reproducible Linux (and macOS-friendly) workstation setup powered by:
- chezmoi for dotfile management & templating
- Ansible for bootstrapping packages & system state
- Modern tooling: Homebrew (Linuxbrew), LazyVim, WezTerm, sway/Wayland environment
Goal: One command to bring a fresh machine to a comfortable, fully-configured environment.
export GITHUB_USERNAME=jvik # replace with your GitHub username (fork first!)
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply "$GITHUB_USERNAME"That chezmoi command will:
- Clone the dotfiles repo.
- Apply tracked files into your home directory.
- Run any
run_once_*andrun_onchange_*scripts (installs Ansible if missing).
Then run the bootstrap playbook (if not already done):
~/.local/share/chezmoi/run_install_02.sh # executes ansible-playbook with privilege escalation promptThe install script defaults to ANSIBLE_VERBOSITY=1 for extra task output. For deeper troubleshooting, increase it temporarily:
ANSIBLE_VERBOSITY=2 ~/.local/share/chezmoi/run_install_02.sh
ANSIBLE_VERBOSITY=3 ~/.local/share/chezmoi/run_install_02.shYou can re-run safely; tasks are idempotent.
Minimal before first run:
- curl & git (for initial chezmoi installer)
- A POSIX shell (bash)
- sudo access (for package installs)
Automatically handled / installed:
- Ansible (via
run_once_01_install_ansible.shfor Fedora. Other distros are not tested, but Ubuntu/Debian will likely work.) - Homebrew (Linuxbrew) if not present (installed by Ansible playbook)
Playbook: dot_bootstrap/setup.yml
Automatically executed by chezmoi.
Key tasks:
- Install base packages (fd-find, tree, flatpak, ansible-lint, htop, blueman, wezterm etc.)
- Sway stack install (sway, waybar, fuzzel, SwayNotificationCenter, wdisplays, lxpolkit)
- Flatpak application installation
- Set login shell to fish for user
- Install Homebrew (if missing) and package set.
- Install fonts via Homebrew casks
Template vars file created at ~/.bootstrap/vars.yml from vars.yml.tmpl.
Dry run / lint (optional):
ansible-lint dot_bootstrap/setup.yml
ansible-playbook -i localhost, -c local --check ~/.bootstrap/setup.ymlNeovim loads via private_dot_config/nvim/init.lua which bootstraps LazyVim with plugins in lua/plugins/ (examples: colorscheme, hop, tmux navigator). Customize by adding plugin specification files under lua/plugins/ or editing lua/config/ (options, keymaps, autocmds).
Update plugins:
nvim +Lazy sync +qallStyle formatting controlled via stylua.toml.
Sway is the window manager. Configuration lives under:
private_dot_config/sway/config— main sway config and color schemesprivate_dot_config/waybar/— status bar config & styleprivate_dot_config/swaync/— notificationsprivate_dot_config/fuzzel/— launcher
Lock script: private_dot_config/sway/lockman.sh.
Keyboard shortcut overlay: $mod+? opens a searchable fuzzel palette of every keybinding, built by scripts/sway-shortcuts.sh parsing the live sway config (including included files) at invocation time — there is no cheatsheet file to keep in sync. Bindings are grouped by the ## section headers already in the config, mode bindings are shown prefixed with the key that enters the mode ($mod+p → r), and selecting an entry runs it via swaymsg. Descriptions are derived from the sway command; to override one, put a #: some description comment on the line directly above the bindsym (sway ignores it). Run scripts/sway-shortcuts.sh --dump to inspect the parsed rows without opening the overlay.
Network management: clicking the wlan tile in waybar (or the network icon in the swaync quick actions) opens networkmanager_dmenu via fuzzel — lists APs with signal strength, connects/forgets networks, and includes a "Rescan WiFi Networks" action (unlike nmtui). Installed by the extras Ansible role; configured at private_dot_config/networkmanager-dmenu/config.ini.
Screenshots: $mod+p / Print freezes the screen with wayfreeze and opens a sway mode to pick region/full/window capture (r/f/w) — see scripts/satty-screenshot.sh. The frozen overlay ensures the capture matches what was on screen when the shortcut was pressed, not whatever's on screen once you finish selecting. Since satty is a plain xdg-toplevel and sway renders it behind a fullscreen window, the script drops fullscreen on the focused workspace once the capture is on disk and restores it when satty exits. Installed by the extras Ansible role.
Some files contain hardware identifiers or device settings tied to specific machines. Review and update these when setting up on new hardware:
private_dot_config/kanshi/config— Display profiles. Per-family glob profiles ("Samsung Electric Company LS49C95xU *") cover most desks and a finalfallback-dockedcatch-all handles anything unrecognised, so a new monitor usually needs no profile at all. Add one only when a desk needs different geometry, withscripts/kanshi-append-config.sh(which inserts before the catch-all) or by editing directly. kanshi takes the first matching profile, sofallback-dockedmust stay last.private_dot_config/sway/config— Touchpad input device IDs (e.g.input "1739:52839:SYNA8018:00_06CB:CE67_Touchpad") and the wallpaper path (/home/jorgen/.wallpaper).private_dot_config/solaar/config.yaml— Logitech peripheral settings containing per-device serial numbers (MX Master 3S, MX Keys, etc.).dot_var/app/hu.irl.cameractrls/— Camera control settings with PCI/USB device identifiers encoded in the filenames.
Common chezmoi commands:
chezmoi diff # See pending changes
chezmoi edit <file> # Edit a managed file in $EDITOR
chezmoi apply # Apply all changes
chezmoi update # Pull latest from origin (dotfiles repo)Regenerate templates after editing vars:
chezmoi apply ~/.bootstrap/vars.yml.tmplRe-run provisioning:
~/.local/share/chezmoi/run_install_02.sh- Add new packages: edit
dot_bootstrap/setup.yml(group by function; keep idempotent). - Add secrets: use chezmoi encryption (
ageorgpg) and keep them out of public repo. Prefer.tmplwith environment lookups instead of committing raw secrets. - Extend fish: add functions under
private_dot_config/fish/functions/. - Override local-only settings: create
private_dot_config/fish/local.fish(seelocal.fish.example). chezmoi can ignore or manage with encryption.
https://drive.proton.me/urls/K1NFJPP43M#p1daHRRboBCZ
Add to ~/.wallpaper
The interactive shell is fish (private_dot_config/fish/, documented in its own
README).
Shortcut picker: ab fuzzy-finds every abbreviation, alias and custom function and puts the
chosen name on the command line, so <space> expands it and you learn the shortcut rather
than just running the command — the terminal counterpart to $mod+? in sway. The list is built
from abbr --show, alias and functions at invocation time, so there is no cheatsheet file to
keep in sync; of the ~229 entries only ~65 come from abbr.fish, the rest from the
lewisacidic/fish-git-abbr plugin. fzf matches against the expansion as well as the name, so
ab commit finds gcm. Run ab --dump to inspect the parsed rows without opening the picker.
Utility scripts live in scripts/. Example: present-select.sh (likely a helper for presentation profile selection). Make scripts executable:
chmod +x scripts/*.shAdd to PATH (fish):
fish_add_path $HOME/scriptsThis repository (dotfiles and original configuration content) is released under the Apache License 2.0. See private_dot_config/nvim/LICENSE for the license text. Third-party tools, plugins, and fonts retain their respective licenses.