Skip to content

Repository files navigation

SMS Supercharge-My-Shell

Dotfiles for fish, neovim, tmux, git and a niri desktop. Configs are linked into ~ with GNU Stow; tools are installed with mise. Runs on Arch (CachyOS), macOS, WSL2 and headless Linux servers.

Layout

base/        stow packages every machine gets: fish git nvim tmux starship lazygit ghostty
             herdr claude ccstatusline mise sesh
desktop/     Linux desktop only: niri noctalia (v5, ~/.local/state/noctalia/settings.toml)
macos/       macOS only: karabiner
plugins/     Claude Code local plugin marketplace (referenced by path, not stowed)
memory/      Claude Code memories that hold on any machine; linked by `mise run memory`,
             not stowed, since the target path is derived from the checkout's location
system/      root-owned files, mirroring /: greetd config, its PAM stack, the greeter's
             greeter.toml. Installed by `mise run greeter`, not stowed
pkglist/     pacman / AUR / apt package lists
Brewfile     Homebrew packages for macOS and WSL
mise.toml    tasks (see below); mise-tasks/ holds the scripts
lib/         ui.sh (colours, Y/n prompt) and plan.sh (what a task would do), sourced by
             the tasks; bootstrap.sh inlines its own copy since it runs before the clone
bootstrap.sh     the one command: OS packages, clone, then `mise run setup`
.stowrc      --target=$HOME --no-folding --dir=base

Each package mirrors ~: base/fish/.config/fish/... links to ~/.config/fish/.... Package READMEs: claude, ccstatusline, memory, git, nvim, karabiner.

Profiles

A profile is the set of layers a machine links. It is detected automatically and can be forced with DOTFILES_PROFILE=.

Profile Layers Detected when
base base Linux without niri (servers), WSL
desktop base + desktop Linux with niri installed
macos base + macos macOS

Install

One command, on a fresh machine or an existing checkout, and safe to re-run:

curl -fsSL https://raw.githubusercontent.com/AH-Merii/SMS-Supercharge-My-Shell/main/bootstrap.sh | sh   # fresh machine
./bootstrap.sh                                                                                          # existing checkout

bootstrap.sh installs git, stow, fish and mise with the OS package manager (Homebrew on macOS and WSL), clones the repo to ~/SMS-Supercharge-My-Shell if needed, and runs mise run setup: OS packages, symlinks, tools, plugins and, on the Arch desktop, the login screen. Files already sitting where a link belongs are moved to <name>.bak, never overwritten.

Nothing installs before you have seen it. Both steps print what they are about to do — packages split into what is already installed and what is not, the stow layers and any files that would be backed up, the missing mise tools — and ask Proceed? [Y/n], default yes. setup asks once for all its steps; answering yes there also skips pacman's and apt's own prompts, since the plan already named every package. paru is the exception: its PKGBUILD review survives, because the plan never showed you a PKGBUILD.

./bootstrap.sh -y                     # accept everything, including paru's review
SMS_YES=1 mise run setup              # same, for the setup half only
curl -fsSL <url> | sh -s -- -y        # unattended, piped
mise run deps                         # any single task previews and asks too
NO_COLOR=1 mise run setup             # plain text

Two things stay manual because they need you: chsh -s "$(command -v fish)" for the login shell, and ggh op init (or ggh init) for git identity and commit signing. fish prints a reminder until the latter is done.

Tasks

Task What it does
setup deps, link, tools, plugins, greeter, memory in order
deps OS packages: pacman/paru on Arch, apt on Debian, brew bundle on macOS/WSL
link Stow the layers for this profile; conflicting files go to .bak (STOW_FLAGS=-n to dry-run)
unlink Remove those symlinks
check Dry-run link
tools mise install everything in the global mise config
plugins fisher + fish plugins, TPM + tmux plugins
greeter Arch desktop: greetd + noctalia-greeter as the login screen, synced to the Noctalia theme; a no-op elsewhere
memory Link the portable Claude Code memories into this checkout's project directory, and add any missing MEMORY.md lines
profile Print the detected profile

Run with mise run <task>; mise tasks lists them. Every task except check and profile previews what it would do and asks first; SMS_YES=1 skips the asking. The preview code lives in lib/plan.sh and is shared, so a task's own preview and the combined one setup prints cannot disagree.

Where a dependency goes

  1. mise (base/mise/.config/mise/config.toml) for anything mise registry <tool> or a github:/npm:/cargo: backend can install: runtimes (node, bun, go, rust, uv) and CLI tools (neovim, starship, ripgrep, fzf, ...). Same versions on every OS, no root needed. mise use -g <tool> edits the stowed file, so commit the result.
  2. pkglist/ on Arch and Debian, Brewfile on macOS and WSL, for what mise cannot build: fish, stow, tmux, gnupg, luarocks, GUI apps and fonts. Desktop-only packages go in pkglist/arch-desktop.txt; AUR packages in pkglist/aur.txt.

Homebrew is not installed on Arch: brew shellenv would put its own python, perl and git in front of pacman's.

Stow

.stowrc sets the target to ~, defaults the package dir to base/, and turns off folding so directories in ~ stay real directories and runtime files (fish history, tmux plugins, Noctalia's generated files) never land in the repo.

stow fish                 # link one base package
stow -d desktop niri      # link a package from another layer
stow -D fish              # unlink
stow -n fish              # dry-run

Stow refuses to overwrite a real file. mise run link moves such files to <name>.bak first; when calling stow by hand, move them aside yourself. Do not use --adopt, it copies the old file into the repo.

Machine notes

  • Arch desktop (CachyOS niri + Noctalia). GPU drivers come from the installer (chwd); enable persistence with sudo systemctl enable nvidia-persistenced if wanted. Noctalia v5 keeps its settings in ~/.local/state/noctalia/settings.toml, which the settings UI writes to; that file is a symlink into desktop/noctalia, so GUI changes show up in git status and you commit the ones you mean to keep (noctalia config validate checks it). Monitor names, wallpaper paths and battery device paths in it are machine-specific. niri includes noctalia.kdl, which Noctalia generates from the theme templates; mise run link creates an empty placeholder for the first login. The login screen is greetd running noctalia-greeter (Wayland, no Xorg) instead of the installer's sddm. mise run greeter installs the files from system/, flips the enabled display manager (effective at the next boot; sddm stays installed as the way back), and runs noctalia msg greeter-sync so the wallpaper, palette and monitor layout match the desktop (restarting Noctalia once if it started before the greeter was installed, as it has on a fresh machine). settings.toml keeps that sync automatic and turns on Noctalia's polkit agent, which is what puts the sync's password prompt on screen. /etc/pam.d/greetd carries pam_gnome_keyring, so the login password still unlocks the keyring.
  • macOS. Homebrew installs the casks in the Brewfile (ghostty, karabiner-elements, 1password, fonts). Add $(command -v fish) to /etc/shells before chsh.
  • WSL2. apt covers the base packages, Homebrew supplies mise and a current fish. The clipboard goes through clip.exe in fish and tmux automatically.
  • Servers. base profile only; nothing desktop-related is linked or installed.

Shell

fish, with starship for the prompt and fisher plugins from fish_plugins. Some commands are replaced outright:

Command Replacement
cat bat
grep ripgrep
ls eza
diff delta

--help anywhere on a command line pipes that tool's help through bat, so it is coloured.

Colours

One scheme, One Dark, defined once: ghostty/themes/OneDark is the terminal's palette, and every shell tool names its colours by palette slot rather than by hex. fish (conf.d/07-theme.fish), fzf, starship, tmux, bat and delta all resolve through the terminal, and eza, ripgrep, fd and git already did. Changing the scheme means changing that one file (and neovim's colorscheme, which keeps its own truecolor palette). The slots carry these roles:

Slot Role
0 surface grey, a step above the background: selection, current line
8 comment grey: comments, autosuggestions, fzf chrome
9–15 lighter tints of 1–7, so "bright" still reads as emphasis
16 orange: numbers and constants, starship's stash and rebase marks
17–20 diff backgrounds: removed, added, and the changed words in each
21 the background, for dark text on a coloured tmux tab

bat's ansi-roles.tmTheme maps token roles to those slots and delta reads the same theme, so cat, previews and diffs share the prompt's colours. bat only sees it through its cache, which mise run link builds and mise rebuilds whenever it installs bat. Slots 16–21 exist only in the ghostty theme: another terminal shows xterm's black and blues there.

hints

hints (or Ctrl+?) opens a searchable cheatsheet of key bindings, abbreviations, aliases and functions, all at once or one group per hotkey inside the picker; hints GROUP and keys open on one group. Enter puts the highlighted name on the command line (a key binding runs instead), Alt+Enter runs it.

Nothing is written by hand except the key bindings. Abbreviations show their expansion, aliases their body, functions their description, and the preview adds the --help of what an entry runs when that is safe to fetch on every cursor move. Bindings are read live from bind --user, so the list cannot go stale; keys_bind KEY COMMAND LABEL [DETAIL...] binds and describes in one call, and anything bound another way still shows, marked "no description" and sorted first. fzf.fish's defaults are disabled in conf.d/20-fzf.fish and re-bound there through keys_bind, as are fzf's own Ctrl+T and Alt+C. Each group is a _hints_rows_GROUP function emitting the same row format, so a new group is one more of those.

Environment

$OS_KIND (linux, macos, wsl) is set once in conf.d/00-os.fish; Homebrew, the 1Password SSH agent socket and the clipboard command branch on it. conf.d/01-env.fish moves gpg to ~/.local/share/gnupg and creates it, since gpg only auto-creates ~/.gnupg.

About

Supercharge your shell, with this easy to setup installation script.

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages