Skip to content
GitHub

The setup script

setup is one bash script with verbs and flags. It is bash because it has to run before anything else is installed. One verb at a time; ./setup on its own, or ./setup help, prints the list.

Terminal window
./setup <verb> [flags]
VerbWhat it doesTouches
installEverything, in order: packages, the user folders, oh-my-zsh, sync, system, plugins, then the extras, once each.Packages, $HOME, /, hyprpm, the extras’ programs
updategit pull --autostash --ff-only on the branch you are on (main holds the releases), says which version it moved from and to, then runs install from the setup just pulled, with the same flags. With no upstream branch, installs what is there.The checkout, then as install
uninstallRemoves every installed file not edited since, in $HOME and /, and puts back what the install moved aside.$HOME, /, the backups

install ends by saying to log out and in again: the shell and the wallpaper daemon only start with a new Hyprland session.

VerbWhat it doesWhen to run it
packagesInstalls what packages/pacman.txt lists and is missing, with sudo pacman -S --needed, then packages/aur.txt with yay or paru. Offers to build yay-bin (or the --aur-helper one) when neither is installed.After a pull adds a package.
syncCopies home/ into $HOME. When the shell’s files changed, it asks the running shell to reload once the last one has landed. Creates the greeting’s scenes and the impasto icon theme if they are missing, and records the version Settings → System shows.After editing the repository.
systemCopies system/ into / with sudo, creates /var/lib/impasto/faces, and enables sddm from the next boot where no other display manager is enabled.After a change to the login screen or the other system files.
pluginsBuilds and enables hypr-dynamic-cursors and hyprglass with hyprpm, then reloads them. Does nothing outside a running Hyprland.Inside the session, when the plugins are missing.

A package counts as installed when something provides it, so fnm-bin satisfies fnm.

What a copied file cannot hold, install sets up once. Each extra is a verb of its own. One that cannot run yet — its program open, Spotify never started, no network — is skipped with the reason and tried again by the next install or update. After that only its own verb runs it, so a setting you change in one of those programs stays. uninstall forgets which ones ran, so an install after it sets them up again.

VerbWhat it doesNeeds
defaultsMakes imv open pictures, neovim text, Thunar folders and Zen web pages and PDFs. A line is skipped whole when a default of yours is already set for any of its types, and so is a program that is not installed. Then GTK applications dark, with the impasto icons.A terminal inside the session
cursorsFetches the Bibata vector cursor into ~/.local/state/quickshell/cursor-src and builds it in the chosen colour, so shake to find stays sharp. install runs it whenever the cursor has not been built.hyprcursor, and the network
thunarApplies Thunar’s settings and its right-click entries, Set as Wallpaper among them.Thunar, closed
vscodiumInstalls four extensions from Open VSX and merges the editor’s settings. The theme lands on the next window.VSCodium, and the network
vesktopTicks the palette’s theme in Vencord’s settings.Vesktop, closed
spotifyPatches Spotify with spicetify so it takes the palette, after asking to make /opt/spotify writable. install runs it again whenever a Spotify update has taken the patch away.spicetify, and a Spotify opened once

Thunar and Vencord write their settings back while they run, which is why both must be closed. Patching Spotify restarts it, so install waits for it to be closed too. Run on its own, a verb stops with the reason where install would skip. Applications covers each program.

VerbWhat it does
checkThe syntax checks CI runs: every Python, Lua, zsh, JSON and TOML file under home/, and setup itself. Needs luac, from the lua package.
helpPrints the verbs and flags. -h and --help do the same.
FlagVerbsEffect
--skip-packagesinstall, updateLeave the packages alone.
--skip-systeminstall, updateLeave / alone.
--skip-pluginsinstall, updateDo not build the plugins.
--aur-helper NAMEinstall, update, packagesyay or paru. The one installed is used; when there is neither, this one is built from the AUR. yay if unset. Also written --aur-helper=NAME.
--noconfirmanyAnswer every question with its default, pacman’s and the AUR helper’s included.
-n, --dry-runanySay what would change, and change nothing. Opens with dry run — nothing on this machine is changed.
-w, --watchsyncCopy again every time a file under home/ is saved. Needs inotify-tools. Stop it with Ctrl C.

Every file sync, system and update handle gets one line:

WordMeaning
newNothing was there; the file was written.
updatedThe installed file was unedited, and the repository’s replaced it.
replacedA file or link that setup did not write was in the way; it is in the backups.
keptYou edited the installed file; the repository’s is beside it as .new.
removedThe file left the repository and was unedited, so it was deleted.
leftThe file left the repository, but you edited it, so it stays.
unlinkedA symlink into the repository was removed, so a copy could take its place.
nothing to doEverything already matches.

A sync that changed the shell’s files ends with reloaded the shell. An extra that has to wait says skipped, with the reason and the verb that sets it up.

uninstall prints restored for each file it puts back. It also reports how many could not go back because their path is taken.