My personal dotfiles collection, designed for consistency across macOS and Debian/Ubuntu systems using Bash or Zsh, with a separate Windows PowerShell preview path.
-
🧼 Clean Structure: Configuration logically separated into
general/,git/, andnano/directories. -
✅ Shell Compatibility: Works seamlessly with both Bash and Zsh.
-
🚀 Intelligent Installer (
install.sh):- Symlinks configurations into your
$HOMEdirectory (default). - Automatically backs up existing conflicting files (
.bak.<timestamp>). - Supports copy mode (
--copy) instead of symlinking. - Offers minimal setup (
--minimal) for core files only. - Provides dry-run (
--dry-run) to preview changes. - Includes force mode (
--force) to skip prompts. - Optional backup cleanup (
--clean-backups).
- Symlinks configurations into your
-
🛠️ Optional Tool Installation: Installs useful tools via a macOS Brewfile or apt (Debian/Ubuntu):
fzf(Fuzzy finder) + keybindings/completionseza(Modernlsreplacement)zoxide(Smartercd) with shell initbat(Syntax-highlightingcat) withbatcatshim on Ubuntufd(Fastfind) withfdfindshim on Ubunturipgrep(rg, fast grep)jq(Lightweight JSON processor)delta(Enhanced Git pager/diff viewer)gh(GitHub CLI)oh-my-posh(Customizable prompt)exiv2(Needed forren_picsfunction)fastfetch(System info display - preferred)nano(Ensures a consistent editor is available)shellcheck(Shell script static analysis)shfmt(Shell script formatter)uv(Python tooling manager; can optionally install CPython 3.13 under~/.local)swiftly(Swift toolchain manager; installed but does not install a Swift toolchain)- macOS also applies a small recommended
defaultsbaseline for typing, Finder, Dock, and screenshots, plus an optional saved Dock layout
-
🪄 Enhanced Shell Experience:
- Sensible command history settings with cross-session sharing.
oh-my-poshintegration for an informative prompt (interactive shells only).- Helpful aliases and functions for common tasks.
- Discover aliases quickly: run
aato print a readable alias list (nice_print_aliases).
-
⚙️ Git Enhancements: Useful Git aliases, functions (like
fzfbranch switching), and recommended global settings (pull.rebase,rebase.autostash,core.editor,core.excludesfile).- Examples:
gl(pull current branch with rebase/autostash),gp(push current branch),gsu(set upstream),gla/glaf(last commit summary/full),lg/lgr(commits missing on origin/release).
- Examples:
-
🔒 Private Aliases: Supports loading personal, untracked aliases from
~/.private_aliases. -
🪟 Windows Preview:
install.ps1bootstraps a small PowerShell profile pluswinget-based Windows manifests, separately from the Bash/Zsh path.
.
├── general/ # Shared shell config (aliases, functions, history, prompt)
├── git/ # Git-specific aliases, functions, and global ignore
├── macos/ # macOS Brewfile and system defaults
│ ├── Brewfile
│ ├── dock.sh
│ └── defaults.sh
├── nano/ # Nano text editor configuration
├── windows/ # Minimal PowerShell profile for Windows
│ ├── omp/
│ │ └── tokyo.omp.json
│ ├── packages.optional.psd1
│ ├── packages.private.example.psd1
│ ├── packages.psd1
│ ├── terminal/
│ │ └── settings.json
│ ├── profile.local.example.ps1
│ └── profile.ps1
├── install.sh # Recommended installation script
├── install.ps1 # Windows/PowerShell installer preview
├── old_setup.sh # DEPRECATED: Legacy copy-with-backup installer
└── README.md # This file-
Clone the repository (Recommended location:
~/.dotfiles):git clone https://github.com/alsd4git/dotfiles ~/.dotfiles -
Navigate into the directory:
cd ~/.dotfiles
-
Make the installer executable:
chmod +x install.sh
-
Run the installer:
./install.sh
- The script will guide you through the process, asking for confirmation before installing optional tools, recommended macOS defaults, and the saved Dock layout unless run with
-for-a.
- The script will guide you through the process, asking for confirmation before installing optional tools, recommended macOS defaults, and the saved Dock layout unless run with
Installer Options:
./install.sh --helpor-h: Show help message../install.sh --dry-runor-dr: Show what would be done without making changes (no file writes, no deletions, no global Git config changes)../install.sh --copyor-c: Copy files instead of creating symlinks (backs up existing files)../install.sh --forceor-f: Skip all prompts, assumes yes to optional installs and backup cleaning../install.sh --minimalor-m: Install only core dotfiles, skip optional tools and Git config../install.sh --allor-a: Automatically install all optional tools without prompting../install.sh --uninstall: Remove symlinks and revert shell rc additions this installer made, including Homebrew bootstrap entries on macOS (runs uninstall flow only, then exits)../install.sh --clean-backupsor-cb: Offer to remove old.bak.*files created by this script in$HOME(or preview removals in dry-run mode).
The Windows path is intentionally smaller and currently focuses on PowerShell profile setup plus package manager bootstrap.
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
.\install.ps1The Windows installer backs up any conflicting profile or Git ignore file as .bak.<timestamp> before copying the shared version into place, and it also creates the optional local overlay directory used by the public profile loader.
It also applies the same recommended global Git defaults as the Bash/Zsh installer path, so Git behavior stays consistent across machines.
There is also a tracked example at windows/profile.local.example.ps1 you can copy or adapt for local-only tweaks.
The installer copies the curated Windows package baseline into ~\.config\dotfiles\windows\packages.psd1 and the optional extras into ~\.config\dotfiles\windows\packages.optional.psd1, so the shared manifests stay available even after the repo is moved or not mounted.
There is also a tracked template at windows/packages.private.example.psd1 that can be copied to ~\.config\dotfiles\windows\packages.private.psd1 for local-only package entries.
If you want to remove old Windows backup files later, run .\install.ps1 -CleanBackups and confirm the prompt, or add -Force to skip the confirmation.
The Windows bootstrap assumes winget is already available through App Installer.
The Windows profile also exposes a to inspect commands, aa to print aliases, plus update helpers like npmupg and wingup.
The installer does not reload the active PowerShell session in place, which keeps the current prompt stable. Open a new PowerShell window after installation, or run rld manually if you want to re-source the profile.
There are curated public manifests in windows/packages.psd1 and windows/packages.optional.psd1 that track the starter baseline by package manager:
wingetfor core shell/runtime apps and Store-backed desktop appsBitwarden,Chrome,Quick Share,Telegram,Android Studio,Keyguard,RustDesk,Tailscale,Zen Browser,UniGetUI, and the rest of the desktop apps you asked for live in the optional extras manifest- Cross-platform CLI tools that are equally useful on Windows now include
shellcheck,shfmt,yq,ast-grep,actionlint,pandoc,ffmpeg, andExifTool NpmGlobalremains intentionally empty so we do not encode machine-specific or personal globals into the repo- If a future app only exists through Microsoft Store, the Windows manifest already supports
Source = 'msstore'on a Winget entry; for now we only use that when it is genuinely needed.
The current Windows prompt theme is tracked in windows/omp/tokyo.omp.json, the minimal Windows Terminal settings live in windows/terminal/settings.json, and JetBrainsMono Nerd Font is part of the core winget baseline. The live prompt resolves the installed oh-my-posh theme folder once, preferring the AppX install location when available, and caches it under AppData\Local so the profile stays simple while still adapting to the installed path.
The installer prints a summary of the manifests, shows a short alias cheat sheet, and can install only the missing items after an explicit confirmation, so you can rerun the bootstrap as many times as needed without duplicating work. Use -y if you want to answer yes to all installer prompts without typing each confirmation.
For machine-specific PowerShell tweaks, keep them outside the repo in one of these optional local overlays:
~\.private_profile.ps1for one-off overrides~\.config\dotfiles\windows\profile.d\*.ps1for ordered local fragments
The public profile loads those overlays last, so they can override the shared defaults without forcing personal details into the repo.
- Detects OS and Shell: Determines if you're on macOS or Debian/Ubuntu Linux, and using Bash or Zsh.
- Creates Symlinks (Default): For each configuration file (e.g.,
general/.aliases), it creates a symlink in your home directory (e.g.,~/.shell_aliases) pointing back to the file in the~/.dotfilesrepository.- If a file or symlink already exists at the destination, it's backed up as
~/<filename>.bak.<timestamp>.
- If a file or symlink already exists at the destination, it's backed up as
- Updates RC Files: Adds lines to your
~/.bashrcor~/.zshrc(creating them if they don't exist) to source the new alias, function, history, and prompt files. It checks if lines already exist to avoid duplicates. - Configures Global Git Ignore:
- Symlinks
git/global.gitignoreto$HOME/.global.gitignore. - Runs
git config --global core.excludesfile "$HOME/.global.gitignore"to tell Git to use this file.
- Symlinks
- Sets Git Defaults: Configures recommended global Git settings:
pull.rebase = true,rebase.autostash = true,core.editor = nano. - Installs Optional Tools (if confirmed or
--all/--force): Usesbrew(macOS) orapt(Debian/Ubuntu) to install tools listed in the Features section.- If Homebrew is missing on macOS, the installer bootstraps it and sets up shell env automatically (adds
eval "$(/opt/homebrew/bin/brew shellenv)"oreval "$(/usr/local/bin/brew shellenv)"depending on install path). - On macOS, the tool manifest lives in
macos/Brewfile, the baseline defaults live inmacos/defaults.sh, and the saved Dock layout lives inmacos/dock.sh. - On Ubuntu/Debian, the
batbinary may be namedbatcat, andfdasfdfind. The installer creates shims (/usr/local/bin/batand/usr/local/bin/fd) for a consistent experience. - For Python/Swift tooling, the managers are installed (
uv,swiftly), and the script can optionally install CPython 3.13 viauvor the latest stable Swift toolchain viaswiftly. - Ensures
~/.local/binis onPATH(if the directory exists) so user-installed tools likeuvandswiftlyare available. - On Linux,
swiftlyis installed from the official Swift.org tarball flow and initialized with--skip-installto avoid installing a Swift toolchain by default. - On Linux,
swiftlyrequiresgpgfor signature verification; the installer ensuresgnupgis installed.
- If Homebrew is missing on macOS, the installer bootstraps it and sets up shell env automatically (adds
- macOS Defaults: On macOS, the installer can apply a small
defaultsbaseline for typing, Finder, Dock, and screenshots. - macOS Dock Layout: The installer can also restore the saved Dock apps/folders from
macos/dock.shusingdockutil. - Checks for Dependencies: Verifies if essential commands used by aliases/functions (like
docker,swift,git,nano) are present and warns if not. - Configures Startup Commands (Optional): Asks if you want
nice_print_aliasesandfastfetch(orscreenfetchas a fallback) to run when a new shell starts. These run only in interactive shells. - fzf & zoxide Initialization: If installed,
zoxideis initialized for your shell;fzfkeybindings/completions are sourced when available. - Swiftly Env: On Linux, the installer adds a line to your shell rc to source
~/.local/share/swiftly/env.sh(if present) soswiftlyand installed toolchains are onPATH. - PATH Cleanup: The installer appends a snippet to remove duplicate entries from
PATHwhile preserving order. - Optional Node Tooling: Offers to install or update
nvm(Node Version Manager) to the latest released tag. If installed, your shell will source~/.nvm/nvm.shautomatically.- If no Node is active via
nvm, you can install the latest LTS and set it as default. - If a Node version is already active via
nvm, the installer offers to switch to the latest LTS and set it as default, with a warning that global npm packages are per-version and won’t move automatically. To migrate them later, run:nvm reinstall-packages <previous_version>. - If
corepackis available, it is enabled after installing/switching to LTS to provide Yarn/PNPM shims.
- If no Node is active via
- Optional Python Tooling: Installs
uv(Python tool and package manager). Optionally offers to install CPython 3.13 managed byuvwithpython/python3defaults (does not change your systempython). - Optional Swift Tooling: Installs
swiftly(Swift toolchain manager). Optionally offers to install the latest stable Swift toolchain viaswiftly.
- Legacy Installer: The
old_setup.shscript uses a simple copy-and-backup method. It's kept for historical purposes butinstall.shis the recommended method. - Zsh Default: If you use Zsh, ensure it's set as your default login shell:
chsh -s $(which zsh) - Private Aliases: You can create a
~/.private_aliasesfile to store personal aliases you don't want to commit to Git. The main alias file (general/.aliases) will automatically source it if it exists. - Backups: Old configuration files backed up by the script will have names like
~/.bashrc.bak.1678886400. You can manually remove them (rm ~/*.bak.*) or use the./install.sh --clean-backupsoption. - System Info: The script can run
fastfetchon startup if available. Iffastfetchis not found, it falls back to tryingscreenfetch. Note that the installer only attempts to installfastfetch, notscreenfetch.
- macOS (via Homebrew Bundle)
- Debian/Ubuntu (via apt)
Other Linux distributions are not covered by the installer. You can adapt the scripts or install tools manually on those platforms.
| Platform | Package manager | What the installer does |
|---|---|---|
| macOS | Homebrew Bundle | Bootstraps Homebrew if missing, installs the manifest in macos/Brewfile, applies the recommended defaults in macos/defaults.sh, restores the Dock layout in macos/dock.sh, and updates shell startup files for brew, fzf, zoxide, nvm, and swiftly when relevant. |
| Debian/Ubuntu | apt | Installs core packages, configures gh from the official repository, creates bat/fd shims when needed, and installs swiftly from the official tarball flow. |
| Windows | winget | Installs the PowerShell profile and uses winget for the public baseline. |
- Homebrew not on
PATH: Open a new shell or runeval "$(/opt/homebrew/bin/brew shellenv)"on Apple Silicon, oreval "$(/usr/local/bin/brew shellenv)"on Intel Macs. - No Rosetta bootstrap: The macOS bootstrap is intended for native Apple Silicon. Intel-only software is left to manual installation or a separate, explicit bootstrap path.
nvmdoes not load: Restart the shell or source~/.bashrc/~/.zshrc; if you need a one-off recovery, runexport NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"; nvm use --lts.swiftlyis missing on Linux: Make sure~/.local/share/swiftly/env.shexists and thatgnupgis installed, because signature verification depends ongpg; a manual recovery istest -f "$HOME/.local/share/swiftly/env.sh" && . "$HOME/.local/share/swiftly/env.sh" && swiftly install stable.- Xcode developer tools are missing on macOS: The installer now checks
xcode-select -pandxcodebuild -versionbefore running the macOS package/bootstrap path. If either check fails, install Xcode from the App Store or runxcode-select --installand retry. - Three-finger drag is not taking effect: Set it manually in
System Settings > Accessibility > Pointer Control > Trackpad Optionsand enableUse trackpad for dragging. macOS may not persist that toggle reliably throughdefaults. fzfbindings are missing: Rerun the installer with--allor source thefzfkeybindings and completion files manually from your shell rc.batandfdlook unfamiliar on Ubuntu:batcatandfdfindare the packaged binary names; the installer createsbatandfdshims when it can write to/usr/local/bin.- Prompt customization is not visible:
oh-my-poshonly loads in interactive shells, so non-interactive sessions will not show the prompt theme. wingetis missing on Windows: Install App Installer from Microsoft and retry the bootstrap.- Touch ID for
sudo: On macOS, the installer can only check whether Touch ID is already enabled forsudoand print a manual recovery hint if it is missing. The file to edit is/etc/pam.d/sudo, and the line to add isauth sufficient pam_tid.so. - Stats.app is blocked by Gatekeeper: If Stats is installed via Homebrew but still refuses to open, run
sudo xattr -r -d com.apple.quarantine /Applications/Stats.app/. - Inventory sync: The companion
list-macOS-appsrepo can help snapshot installed Mac apps before you expand or prunemacos/Brewfile. - Windows package baseline: The public starter inventory lives in
windows/packages.psd1andwindows/packages.optional.psd1; treat them as curated baselines, not a dump of every installed Windows app. - Windows package sources: Use
wingetfor GUI apps and for the CLI tools that are available there. Store-only apps that do not resolve reliably inwingetshould stay manual instead of making the bootstrap more fragile;PC Manageris one of those edge cases on some machines. - Windows prompt assets:
windows/omp/tokyo.omp.jsoncaptures the currentoh-my-poshtheme,windows/terminal/settings.jsoncaptures the minimal Terminal defaults, andJetBrainsMono Nerd Fontis bootstrapped through the corewingetmanifest. The live profile points to the installed theme path, prefers the AppX install location when present, and caches the resolved folder underAppData\Localso the prompt stays straightforward. - Windows Terminal cleanup: The template intentionally leaves out machine-specific SSH and one-off profiles; keep those in a local overlay if you still want them.
- Windows reruns are safe:
install.ps1only installs missing packages after you confirm the prompt. - Prompt refresh: If the shell prompt looks stale after a run, use
rldto re-source the profile and refreshoh-my-posh.
After installation, a quick smoke check is:
command -v git nano fzf zoxide uv swiftly gh
git config --global --get core.excludesfileIf you use Zsh, open a new interactive shell and confirm that aa, l, gl, and myip are available.
-
Shell basics:
a/aa: Inspect a command or print aliases.l/lt/ll: Directory listings (useezaif installed, otherwisels).mntlist: Show mounted volumes (portable, does not shadowmount).myip: Show public IP.rld: Reload the current PowerShell profile.brewup: Update, upgrade and clean Homebrew (macOS).
-
Packages and repos:
npmupg: Update all globally installed npm packages (respecting semver ranges).rpx: Run RepoMix and output<folder>-repomix.md, ignoring*.html.
-
Docker helpers:
up_dockers: Pull latest tags for all local image repositories.up_dockers_wt: One-shot updates via Watchtower (--run-once --cleanup).up_portainer_ce/up_portainer_be: Recreate Portainer CE/BE containers with volumes/ports.
-
Git aliases (highlights):
gl/gp: Pull (rebase+autostash) / push current branch.gsu: Set upstream toorigin/<current-branch>.gla/glaf: Show last commit summary / full diff.gd/gds: Diff vs. HEAD / diff stats.gcb/gca/gcd: New branch / amend / amend with now timestamp.lg: Commits on local branch not onorigin/<branch>.lgr: Commits on current branch not inorigin/release.
-
Git fzf functions:
fuzzy_branch_selector: Select a branch (includes remotes); usesgit switchwith tracking.fuzzy_log_viewer: Fuzzy-find commits with preview (git show).git_see_authors: Shortlog authors summary.