Amos Blog

GNU Stow and syncing dotfiles

ยท by Amos

Dotfiles and Organization: A Clean Setup on My New MacBook

After setting up my new MacBook with a focus on clean and minimal installations, I faced two main goals:

  1. Organize the dotfiles in my home directory.
  2. Create a GitHub repository to sync dotfiles across multiple computers.

Hereโ€™s a concise overview of how I tackled these objectives using GNU Stow.


Using GNU Stow to Manage Dotfiles

I followed a great guide by Josean Martinez titled How To Easily Manage Your Dotfiles With GNU Stow.

GNU Stow is the key tool in this setup โ€” easily installable via Homebrew. It works by letting you keep your dotfiles organized in a dedicated directory (usually ~/dotfiles/) and manage symbolic links in your home directory automatically.

For my setup, I organized configurations for:

This approach not only cleaned up my home directory but also enabled me to manage and sync my configuration files easily via GitHub.

Note: I wonโ€™t cover the full setup here since Joseanโ€™s blog post and accompanying YouTube video provide an excellent, step-by-step explanation.


Syncing Dotfiles with GitHub

Once the ~/dotfiles/ directory was well-structured and Stow had created the necessary symlinks, the final step was to push everything to a private GitHub repository.

A small hiccup was that I accidentally started the repository with a master branch instead of main. After a quick fix, I now have a clean dotfiles repo that stores all my configurations online, allowing me to push or pull changes and keep settings consistent across all my devices.

Hereโ€™s a snapshot of my dotfiles repo directory structure for reference:

โ”œโ”€โ”€ .aspell.en.prepl
โ”œโ”€โ”€ .aspell.en.pws
โ”œโ”€โ”€ .config
โ”‚ย ย  โ”œโ”€โ”€ iterm2
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ AppSupport -> /Users/amos/Library/Application Support/iTerm2
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ sockets
โ”‚ย ย  โ”‚ย ย      โ””โ”€โ”€ secrets
โ”‚ย ย  โ””โ”€โ”€ nvim
โ”‚ย ย      โ”œโ”€โ”€ .github
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ ISSUE_TEMPLATE
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ bug_report.md
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ pull_request_template.md
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ workflows
โ”‚ย ย      โ”‚ย ย      โ””โ”€โ”€ stylua.yml
โ”‚ย ย      โ”œโ”€โ”€ .gitignore
โ”‚ย ย      โ”œโ”€โ”€ .stylua.toml
โ”‚ย ย      โ”œโ”€โ”€ doc
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ kickstart.txt
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ tags
โ”‚ย ย      โ”œโ”€โ”€ init.lua
โ”‚ย ย      โ”œโ”€โ”€ lazy-lock.json
โ”‚ย ย      โ”œโ”€โ”€ lua
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ custom
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ core
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ init.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ keymaps.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ options.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ plugins
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ alpha.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ autopairs.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ bufferline.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ colorscheme.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ conform.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ guess-indent.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ indent_line.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ lazydev.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ lazygit.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ lspconfig.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ luasnip.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ mini.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ nvim-cmp.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ nvim-tree.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ telescope.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ todo-comments.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ treesitter.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ vimtex.lua
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย      โ””โ”€โ”€ which-key.lua
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ kickstart
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ health.lua
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ info.lua
โ”‚ย ย      โ”‚ย ย      โ””โ”€โ”€ plugins
โ”‚ย ย      โ”‚ย ย          โ””โ”€โ”€ lint.lua
โ”‚ย ย      โ”œโ”€โ”€ LuaSnip
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ all.lua
โ”‚ย ย      โ”œโ”€โ”€ node_modules
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ .bin
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node-gyp-build -> ../node-gyp-build/bin.js
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node-gyp-build-optional -> ../node-gyp-build/optional.js
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node-gyp-build-test -> ../node-gyp-build/build-test.js
โ”‚ย ย      โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ tree-sitter -> ../tree-sitter-cli/cli.js
โ”‚ย ย      โ”‚ย ย  โ”œโ”€โ”€ .package-lock.json
โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ tree-sitter-cli
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ cli.js
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ dsl.d.ts
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ install.js
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ LICENSE
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ package.json
โ”‚ย ย      โ”‚ย ย      โ”œโ”€โ”€ README.md
โ”‚ย ย      โ”‚ย ย      โ””โ”€โ”€ tree-sitter
โ”‚ย ย      โ”œโ”€โ”€ package-lock.json
โ”‚ย ย      โ”œโ”€โ”€ package.json
โ”‚ย ย      โ””โ”€โ”€ README.md
โ”œโ”€โ”€ .git
โ”œโ”€โ”€ .zprofile
โ”œโ”€โ”€ .zsh_sessions
โ”‚ย ย  โ”œโ”€โ”€ _expiration_check_timestamp
โ”‚ย ย  โ””โ”€โ”€ 0EC8B8A7-66B2-4DB2-82C0-804BC3207BD6.session
โ”œโ”€โ”€ .zshrc
โ””โ”€โ”€ README.md

Pretty neat, if you ask me!


Bonus: Managing .zcompdump Files from Oh My Zsh

Finally, I managed to move the annoying .zcompdump filesโ€”created automatically by Oh My Zsh in my home folderโ€”into a separate directory. This keeps my home clean and avoids clutter.

For anyone facing the same issue, here’s a helpful Stack Overflow post with instructions on how to do this.

#neovim #dotfiles #software