Arch Linux + Hyprland. Everything themed from a single palette file.
| Compositor | Hyprland (Lua config) |
| Bar | Waybar, custom design |
| Launcher | Rofi, list + app grid |
| Terminal | Ghostty (primary), Kitty |
| Multiplexer | tmux, both terminals open into it |
| Font | BlexMono Nerd Font (IBM Plex Mono + Nerd glyphs) |
| Shell | Zsh + Powerlevel10k · Fish + Tide |
| Files | Yazi (SUPER+E), Nautilus (SUPER+SHIFT+E) |
| Editor | Neovim + LazyVim |
| Notifications | Mako |
| Lock / idle | Hyprlock + Hypridle |
| Wallpaper | Hyprpaper |
| Dock | nwg-dock, auto-hide |
| Monitors | nwg-displays (GUI) |
.config/ mirrors ~/.config, one folder per app
.scripts/ executables, symlinked to ~/.scripts (on PATH)
.config/environment.d/ puts ~/.scripts on PATH for systemd user services
theme/ palettes + templates + the render engine
.zshrc these two live in $HOME
.p10k.zsh
Zsh is the login shell; fish is installed alongside (fish to enter it).
Zsh
- oh-my-zsh: framework
- powerlevel10k: prompt
- zsh-autosuggestions: ghost-text completion from history
- zsh-syntax-highlighting: colors commands as you type
Fish
Shared CLI
- eza: ls replacement
- bat: cat replacement
- fd: find replacement
- ripgrep: grep replacement
- fzf: fuzzy finder
- zoxide: cd that learns
- ghq: repository manager
- lazygit: git TUI
- yazi: file manager
- btop: resource monitor
.scripts/ sits on PATH in three places, because three different things
launch them: both shells (.zshrc, config.fish), Hyprland (via an absolute
path in hyprland.lua), and systemd user services (environment.d).
Miss any one and the buttons that call a script fail silently.
theme |
render palette across all apps |
wallpaper |
thumbnail picker for image, monitor, fit mode |
cheatsheet |
keybinding overlay, parsed from the Hyprland config |
powermenu |
lock / suspend / logout / reboot / shutdown |
audio-device |
pick output/input, moves live streams too |
taskmanager · files · dock |
thin wrappers, swap the app in one line |
sddm-install |
install the generated login theme (needs root) |
One palette drives everything:
theme carbonfox # render every template and reload
theme --list # available palettestheme/palettes/*.toml holds the colors. theme/render.py fills the
templates and reloads the running apps.
Fifteen targets stay in sync: Waybar (config + CSS), Rofi (list + grid), Mako, Ghostty, Kitty, tmux, GTK 3/4, btop, Yazi, the dock (CSS + launcher icon), SDDM, and Hyprland's window borders.
The dock's Applications icon uses accent from the active palette, with
an accent_dark shadow. theme/templates/dock-launcher.svg.tmpl generates
theme/dock/launcher.svg, which .scripts/dock loads with -ico.
New theme = copy a palette, change the hex values, run theme <name>.
Never edit generated files. They carry a header pointing at their template.
Derived values are computed, not hand-picked: every color gets _dark (50%)
and _dim (75%) variants, plus _raw (r,g,b) and _hex forms. The bar's
3D shadows and the dock's launcher shadow come from those. Hyprland's active
border is a single flat color (yellow), not a gradient.
sudo pacman -S --needed hyprland hyprpaper hyprlock hypridle hyprpolkitagent \
waybar rofi mako ghostty kitty yazi btop nautilus nwg-dock-hyprland \
nwg-displays nwg-look grim slurp hyprshot wl-clipboard sddm \
zsh zsh-autosuggestions zsh-syntax-highlighting fish fisher \
eza bat fd ripgrep fzf zoxide ghq lazygit neovim stow \
papirus-icon-theme adw-gtk-theme ttf-ibmplex-mono-nerd ttf-jetbrains-mono-nerd \
pavucontrol networkmanager brightnessctl playerctl xdg-user-dirs \
resvg poppler poppler-data imagemagick ffmpeg
git clone <repo> ~/.dotfiles && cd ~/.dotfiles
./install.shinstall.sh renders the theme, creates the wallpaper folder and enables the
user services. Log out and back in so environment.d applies.
SUPER + / opens a searchable cheat sheet, generated by reading
hyprland.lua, so it can't go stale. The full list lives there; below is
just enough to get in.
| Key | |
|---|---|
SUPER + / |
Cheat sheet |
SUPER + Q |
Terminal |
SUPER + R |
Launcher |
CTRL+ALT+DEL |
Session menu |
Both terminals open straight into a session (new-session -A -s main, so a
second window attaches instead of spawning a rival session). If tmux is ever
missing the terminal falls back to zsh rather than failing to open.
Splitting used to be Ghostty's job. It moved here, so the two stopped
competing for the same keys. Prefix is C-b.
| Key | |
|---|---|
C-b | / C-b - |
Split right / down, inheriting the current directory |
C-b h/j/k/l |
Move between panes |
C-b H/J/K/L |
Resize, repeatable without re-pressing the prefix |
C-b z |
Zoom pane |
- This is a personal setup and a work in progress. It's shaped around my machine and my habits, and it changes often. Read it, fork it, take what's useful. Use it at your own risk.
- Monitor layout (
monitors.lua,workspaces.lua) is generated by nwg-displays and gitignored, because it's machine-specific. - Fish is installed but zsh stays the login shell. Run
fishto try it. - Both shells have autosuggestions and syntax highlighting.
- No hardcoded home paths: configs use
$HOME(hyprlang),os.getenv("HOME")(Lua), or theme-by-name (btop). Clone and it works under any username.