dotfiles

nicknisiMIT活跃维护

一套完整的个人开发环境配置,涵盖 vim、zsh、git、Homebrew、neovim、tmux 等工具,可直接参考或复用来搭建自己的终端工作流。

vim, zsh, git, homebrew, neovim - my whole world

暂无版本3,004star371fork同步于 2026-11-10 23:43 UTC

怎么上手

由 README 提炼,执行前请确认
curl -fsSL https://raw.githubusercontent.com/nicknisi/dotfiles/main/install.sh | bash
硬件要求按 README 说明

README 未说明显存或 GPU 要求;宿主环境假定为 Apple Silicon macOS,另提供 Ubuntu devcontainer 用于验证可移植终端配置。

支持 Apple Silicon
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

作者自用的 macOS 开发环境 dotfiles,用 Mise 一键装齐终端、编辑器与桌面工具

一套完整的个人开发环境配置,涵盖 vim、zsh、git、Homebrew、neovim、tmux 等工具,可直接参考或复用来搭建自己的终端工作流。

核心能力

  • 用 Mise 清单统一管理包、仓库克隆与 dotfiles 软链
  • 一条 curl 命令完成裸机 bootstrap,支持 --dry-run 预览
  • 用 theme 命令联动切换 Ghostty、tmux、nvim 等全套配色
  • tmux 前缀改为 control-a,并集成 Fleet 与 lazygit 弹窗
  • AeroSpace 加 SketchyBar 提供窗口管理与状态栏

容易踩的坑

仓库必须放在 ~/Developer/dotfiles,路径写死在清单里;首次运行若缺 Xcode Command Line Tools 会中断,需装完再跑一次;bootstrap 会用 SSH 克隆作者的私有仓库,需配好 GitHub SSH key。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

0 个版本

暂无 release 数据(可能没有发版,或尚未同步)。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Dotfiles

    These are my actual dotfiles, not a starter kit. The host setup assumes Apple Silicon macOS, a checkout at ~/Developer/dotfiles, and several of my other repositories under ~/Developer. The devcontainer runs the same bootstrap in Ubuntu so I can edit and check the portable terminal configuration without changing the host.

    [!NOTE] If you came here from my vim + tmux talk, the repository at the time of that recording is still available. The current setup is substantially different.

    What this sets up

    AreaCurrent choice
    Machine setupMise bootstrap and tasks
    TerminalGhostty, with WezTerm and Kitty configs still tracked
    Shell and promptHomebrew zsh and Starship
    Multiplexertmux
    EditorNeovim with lazy.nvim
    Window managementAeroSpace, SketchyBar, Borders, and Karabiner-Elements
    CLI agentsPi and Claude Code
    Agent orchestrationFleet
    Fonts and colorMonaspace, Symbols Nerd Font, Tokyo Night

    Install

    Run this on a Mac:

    curl -fsSL https://raw.githubusercontent.com/nicknisi/dotfiles/main/install.sh | bash
    

    The installer checks for Git, clones this repository, installs Mise, and runs one full bootstrap. On a Mac without the Xcode Command Line Tools, the first run opens Apple's installer and stops. Run the command again after the tools finish installing.

    The bootstrap expects:

    • Apple Silicon Homebrew paths under /opt/homebrew
    • a working GitHub SSH key for the additional repositories declared in [bootstrap.repos]

    After the install, open a new login shell and configure the machine-local Git identity:

    mise run setup-git
    

    The Git task asks for a name, email, and GitHub username, then writes ~/.gitconfig-local. That file is included by the tracked Git config but never committed.

    Preview the install

    curl -fsSL https://raw.githubusercontent.com/nicknisi/dotfiles/main/install.sh | bash -s -- --dry-run
    

    Set NO_COLOR=1 for plain output.

    Run it by hand

    xcode-select --install # only when Git is missing
    
    git clone https://github.com/nicknisi/dotfiles.git ~/Developer/dotfiles
    curl -fsSL https://mise.run | sh
    export PATH="$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
    
    MISE_GLOBAL_CONFIG_FILE=~/Developer/dotfiles/config/mise/config.toml \
      mise bootstrap --yes --skip-dirty
    

    The explicit MISE_GLOBAL_CONFIG_FILE is only needed before bootstrap creates ~/.config/mise.

    How bootstrap works

    config/mise/config.toml is the machine manifest. A full mise bootstrap does the following work:

    1. On macOS, runs the pre-packages hook that installs Homebrew and the tap packages mise cannot resolve.
    2. Installs the remaining OS-specific packages and macOS apps from [bootstrap.packages].
    3. Clones missing repositories from [bootstrap.repos] without changing existing checkouts.
    4. Applies the [dotfiles] symlinks.
    5. Applies macOS defaults where available and sets the OS-specific login shell.
    6. Installs the runtimes and command-line tools from [tools].
    7. Runs the bootstrap task to register the repository's Git clean filter.

    The installer points Mise at the cloned config, so the same manifest handles the first run and every later run.

    Mise tasks

    mise tasks
    
    TaskPurpose
    mise run bootstrapRegister the pi-settings Git clean filter
    mise run install-homebrewInstall Homebrew with the official installer if needed
    mise run install-tap-packagesInstall the macOS packages unavailable to mise
    mise run setup-gitWrite the machine-local Git identity
    mise run update-allRun every scoped update task in sequence
    mise run update:systemUpdate Homebrew packages
    mise run update:toolsUpdate mise-managed tools, uv tools, and Pi extensions
    mise run update:pluginsUpdate Neovim and zsh plugins
    mise run update:dotfilesFast-forward this repo when it is on main

    Runtimes

    • Node.js 24 and Python 3.14.7
    • pnpm, Bun, Deno, Lua, and tree-sitter

    Command-line tools

    • 1Password CLI, Claude Code, Pi, Wrangler, Greptile, and the WorkOS CLI
    • bat, delta, eza, fd, fzf, GitHub CLI, glow, gum, jq, lazygit, ripgrep, shellcheck, Starship, StyLua, tmux, zoxide, and superfile
    • Neovim
    • diffdad, fleet, tm, and sessions from my GitHub repositories. Linux ARM skips these until their releases include ARM assets.

    System packages and macOS apps

    • newer Bash, Git, zsh, grep, and Vim builds
    • btop, cloc, entr, fswatch, GnuPG, highlight, tree, wdiff, and wget through Homebrew or apt
    • noti, trash, AeroSpace, Ghostty, WezTerm, Karabiner-Elements, SketchyBar, Borders, Monaspace, and Symbols Nerd Font on macOS

    Additional repositories

    Bootstrap clones these over SSH:

    • ~/Developer/pi-extensions
    • ~/Developer/ideation
    • ~/Developer/claude-plugins

    Repository layout

    PathWhat it containsDestination
    config/App configuration~/.config/*
    home/Home-directory configuration~/.claude, ~/.pi, and ~/.zshenv
    bin/Personal commands placed on PATHUsed directly from this checkout
    tools/Larger one-off tools and build helpersRun from the repository
    install.shBare-machine bootstrapRun directly or through curl
    .devcontainer/Ubuntu development environment and smoke testLocal Docker container

    Mise links directories rather than copying individual files. The two declarations are intentionally broad:

    [dotfiles]
    "~/.config/*" = "~/Developer/dotfiles/config/*"
    "~/.??*" = "~/Developer/dotfiles/home/.??*"
    

    The fixed source path is why the repository must live at ~/Developer/dotfiles unless you edit the manifest.

    Manage dotfile links

    mise bootstrap dotfiles status
    mise bootstrap dotfiles apply --yes
    mise bootstrap dotfiles apply --yes ~/.config/nvim
    mise bootstrap dotfiles unapply --yes
    mise bootstrap dotfiles unapply --yes ~/.config/nvim
    

    Unapply a target before deleting or renaming its source. Mise refuses to overwrite a real file with a symlink unless you pass --force.

    To inspect old dangling links:

    find ~/.config -type l ! -exec test -e {} \; -print
    find ~ -maxdepth 1 -type l ! -exec test -e {} \; -print
    

    Those commands only print candidates. Check each target before removing it.

    Shell and prompt

    home/.zshenv establishes the XDG paths, finds the repository through the ~/.zshenv symlink, and exports EDITOR=nvim and GIT_EDITOR=nvim. config/zsh/.zshrc handles the interactive shell.

    The shell config:

    • activates Mise for per-directory tool versions
    • initializes completion, fzf, and zoxide
    • adds the repository's bin/, ~/bin, ~/.local/bin, Bun, Cargo, pnpm, GNU grep, and /usr/local/sbin paths
    • sets CODE_DIR to ~/code when it exists, otherwise ~/Developer
    • installs the local zsh plugins with the zfetch function
    • loads ~/.zshenv.local, ~/.localrc, and ~/.zshrc.local when present

    The configured plugins are zsh-async, zsh-syntax-highlighting, zsh-autosuggestions, zsh-npm-scripts-autocomplete, and fzf-tab. mise run update:plugins pulls their Git checkouts.

    Starship renders a two-line prompt. The left side shows the full directory and a Node version when the directory contains package.json or node_modules. The right side shows Git state, the branch, and suspended jobs. The prompt symbol is cyan after success and red after failure.

    Terminal and macOS desktop

    Ghostty is the terminal this tmux config targets. Its config uses Tokyo Night light and dark themes, Monaspace, a translucent blurred background, CSI-u modified keys, and cmd+s as a prefix for native splits and tabs.

    The bootstrap installs WezTerm too, and a Kitty config remains in the tree.

    AeroSpace starts at login and launches SketchyBar. The basic movement scheme is:

    KeysAction
    alt+h/j/k/lFocus a window
    alt+shift+h/j/k/lMove a window
    alt+1..9 or alt+letterSwitch workspace
    alt+shift+1..9 or alt+shift+letterMove a window to a workspace
    alt+shift+;Enter the AeroSpace service mode

    The AeroSpace rules route terminals, browsers, chat apps, mail, and other applications to named workspaces. SketchyBar shows those workspaces with app icons, the focused window title, the current layout, Fleet state, GitHub review requests, agent spend, Claude usage, and now-playing information. Borders runs as a Homebrew service.

    Themes

    theme switches the whole desktop at once, on Linux and macOS:

    theme                 # pick a theme and wallpaper with fzf
    theme nord 2          # switch; 2 = second wallpaper
    theme next            # cycle (SUPER+0 under Hyprland)
    theme bg next         # only the wallpaper (SUPER+CTRL+0)
    theme picker          # the carousel overlay; "Theme" and "Wallpaper" in wofi open it
    theme list            # every pack with its swatches and tagline
    

    The overlay is config/quickshell/ThemePicker.qml: the chosen wallpaper expanded in the middle, the rest as skewed slices, type to filter, Enter to apply. bin/theme feeds it rows over qs ipc and caches thumbnails under ~/.cache/theme/thumbs.

    A pack is themes/<name>/colors.toml plus backgrounds/; a theme repo laid out that way drops in unchanged. On a switch, bin/theme renders themes/templates/*.tpl from the palette into ~/.local/state/theme/current/theme/ and every app reads from there: ghostty, kitty, wezterm, tmux, nvim (aether), btop, LazyGit, Delta, fzf, Starship, Pi, and Claude Code on both platforms; Hyprland borders, hyprlock, wofi, the Quickshell bar, and GTK dark/light on Linux; the system appearance, SketchyBar, Borders, and Slack on macOS. A pack may ship a file under a template's name to hand-tune that one app. bin/theme-color resolves a colors.toml into the full palette (--all, --json) and is the renderer. Run theme <name> once on a fresh machine: hyprlock and hyprpaper read the state dir and have nothing until then.

    tmux

    The prefix is control-a. I remap Caps Lock to Control, so this is less awkward than the default control-b.

    Key after the prefixAction
    h, j, k, lMove between panes
    H, J, K, LResize a pane by ten cells
    ``
    -Split below
    gOpen lazygit in a popup
    sOpen the tm session picker
    yOpen Fleet in a popup
    nJump to the next waiting agent pane
    fToggle the Fleet sidebar
    TToggle the status bar

    The status bar sits at the top. It shows the session on the left, then Fleet state and Git status on the right. The theme follows the macOS light or dark appearance and uses Nerd Font separators.

    tm is installed as a compiled Mise tool. bin/tm is the fallback implementation and uses fzf to switch, create, refresh, and delete sessions.

    Set TMUX_MINIMAL=1 in a local shell file to hide the status bar while a session has one window:

    export TMUX_MINIMAL=1
    

    The tmux config also forwards truecolor, italics, undercurl, modified Enter keys, OSC 8 links, and terminal graphics through Ghostty. Those settings are there for Neovim and terminal agents, not decoration.

    Neovim

    config/nvim/init.lua calls the local nisi module. That module bootstraps lazy.nvim, loads the plugin specs under config/nvim/lua/nisi/plugins/, and enables the Copilot, Python, and fzf extras.

    The active setup uses a transparent background and chooses the Tokyo Night colorscheme after checking the macOS appearance. The first launch needs network access because it clones lazy.nvim and the plugin set.

    Useful commands:

    nvim          # Open the editor
    vimu          # Run Lazy sync without opening the UI
    

    Open :Lazy inside Neovim to inspect or update individual plugins.

    Git and worktrees

    The tracked Git config lives at config/git/config. It sets main as the default branch, uses delta for paging, rebases pulls, enables rerere, auto-stashes rebases, and includes the untracked ~/.gitconfig-local identity file.

    The worktree tooling is available through Git's external-command convention:

    git wt create my-feature
    git wt create --pr 123
    git wt status
    git wt go
    git wt prune
    

    git wt create resolves local branches, remote branches, and GitHub pull requests before creating a new branch. New branches default to the prefix from git config github.user. git wt status shows dirty, merged, closed, and prunable worktrees.

    Pi, Claude Code, and Fleet

    Both agent configurations are tracked, but their runtime data is not.

    Pi

    home/.pi/agent/settings.json is the Pi configuration. It points at packages from ~/Developer/pi-extensions, the Claude plugin repository, Ideation, Fleet, and several npm or Git packages. Most extension source code lives outside this repository. A fresh clone will only have the extension repositories declared in Mise; some local package paths still require their own checkouts.

    Because ~/.pi is a directory symlink into this repository, .gitignore excludes auth, sessions, memory databases, relay state, subagent runs, package installs, and other runtime files. A Git clean filter strips lastChangelogVersion from settings.json before Git compares or stages it.

    Claude Code

    home/.claude/settings.json and home/.claude/CLAUDE.md are the only tracked Claude files. The settings configure the status line, SessionEnd cleanup, permissions, plugin marketplaces, and enabled plugins. Sessions, caches, downloaded plugins, and credentials remain untracked.

    Three small scripts connect the agent tools to the terminal environment:

    • claude-statusline renders the Claude status and pushes usage updates to SketchyBar
    • claude-tmux-cleanup resets pane state when a Claude session ends
    • claude-notify sends attention notifications through tmux

    MCP servers are user-scoped in ~/.claude.json and are not part of bootstrap. bin/setup-mcp-servers is a one-shot mutating script for the GPT-5, Playwright, and Context7 servers. It requires OPENAI_API_KEY and CONTEXT7_API_KEY, and it runs immediately when invoked.

    Fleet

    Fleet is installed by Mise and lives in its own repository. tmux uses it for agent status, the next-waiting-agent jump, the popup, the sidebar, and window titles. SketchyBar consumes the same state through sketchybar-fleet-watch.

    Commands in bin/

    bin/ is on PATH. The table calls out the larger standalone commands; many of the remaining files support tmux, SketchyBar, Git aliases, or agent status.

    CommandWhat it does
    batteryPrint the current macOS battery percentage
    brew-whyShow installed Homebrew formulae and their installed dependents
    digestBuild a bounded text digest of a Git repository for model input
    npm-trust-setupBootstrap npm packages and GitHub Actions trusted publishing
    wifi-passwordRead a Wi-Fi password from the macOS keychain
    thisisfinePrint the "This is fine" scene in terminal color

    Read a script before running it. Some are one-off commands and do not implement --help or a dry run.

    Updating

    Run every update in sequence with:

    mise run update-all
    

    Run one area with mise run update:system, mise run update:tools, mise run update:plugins, or mise run update:dotfiles. The wrapper stops when a task fails.

    Linux devcontainer

    The devcontainer is a disposable Ubuntu 24.04 environment that runs the real bootstrap. Docker bind-mounts this checkout at /home/vscode/Developer/dotfiles, so source edits persist on the Mac. Installed tools, cloned companion repositories, and editor plugins live in the container and disappear when it is replaced.

    What the files do

    File or servicePurpose
    .devcontainer/devcontainer.jsonTells a Dev Container launcher which image, mount, environment, and lifecycle commands to use
    mcr.microsoft.com/devcontainers/base:ubuntu24.04Supplies the Ubuntu image, Git, zsh, and the non-root vscode user
    config/mise/config.devcontainer.tomlOverrides the macOS login-shell path with /usr/bin/zsh
    .devcontainer/github_known_hostsPins GitHub's published SSH host key
    .devcontainer/smoke-test.shChecks packages, tools, repositories, links, SSH, zsh, Git, Neovim, and tmux

    There is no custom Dockerfile. The official base image already has the prerequisites that install.sh needs, and Mise owns the rest.

    Start and enter it

    Install the reference CLI once and start OrbStack or Docker Desktop:

    brew install devcontainer
    devcontainer up --workspace-folder .
    

    The first up creates the container, forwards the macOS SSH agent without copying key files, runs install.sh, and runs the smoke test. Unlock 1Password if it asks to approve an SSH operation. Enter the resulting zsh login shell with:

    devcontainer exec --workspace-folder . zsh -l
    

    Inside that shell, use nvim, tmux, Git, and the other installed tools normally. Changes under ~/Developer/dotfiles are changes to the host checkout.

    Check, rerun, and rebuild

    Run the smoke test again:

    devcontainer exec --workspace-folder . .devcontainer/smoke-test.sh
    

    Rerun bootstrap after changing the Mise manifest or installer:

    devcontainer exec --workspace-folder . zsh -lc 'NO_COLOR=1 bash install.sh'
    

    Replace the container and prove setup works from an empty home directory:

    devcontainer up --workspace-folder . --remove-existing-container
    

    Docker is the verified container engine. OrbStack and Docker Desktop both expose the SSH agent at the mounted /run/host-services/ssh-auth.sock path. DevPod can read the same devcontainer.json with its Docker provider, but adds no value for this local workflow. Podman is not verified because it does not provide this Docker-specific SSH bridge.

    Local changes and forks

    Machine-only shell changes belong in one of these ignored files:

    • ~/.zshenv.local
    • ~/.localrc
    • ~/.zshrc.local

    Before using this repository as your own, search for nicknisi, /Users/nicknisi, and ~/Developer. The Mise manifest, Claude marketplaces, agent package paths, Git aliases, and application rules all contain personal assumptions.

    For hardware and software that do not belong in dotfiles, see nicknisi.com/uses.

    License and questions

    The repository is MIT licensed. For questions, use GitHub Discussions.