Blog

  • my dev dotfiles setup: neovim, tmux, zsh and why you should steal it.

    Every great developer has a secret weapon hiding in their home directory.

    It’s not a framework, a SaaS tool, or a $500 keyboard. It’s a folder called
    dotfiles — and it’s the difference between a generic terminal that slows you
    down and a tailored environment that disappears and lets you think.

    This is my setup. Here’s what’s in it, how it’s built, and why every decision
    was intentional.


    Dotfiles are the hidden configuration files that live in your home directory —
    .zshrc, .tmux.conf, the entire ~/.config/nvim folder. They define how
    every tool you use behaves: your editor, your shell, your terminal, your git
    workflow.

    Most developers cobble theirs together over years, copy-pasting from Stack
    Overflow, never fully understanding what half of it does. The result is a
    machine you can’t reproduce, can’t share, and can’t trust.

    A well-structured dotfiles repo solves that. You clone it, run one command, and
    your full environment is live in under ten minutes — on any machine.


    ## The Stack at a Glance

    ToolPurpose
    Neovim 0.11+Main editor — LSP, autocomplete, GitHub Copilot, debugging
    TmuxTerminal multiplexer — persistent sessions, split panes
    Zsh + oh-my-zshShell — autosuggestions, syntax highlighting, vi keybindings
    AlacrittyGPU-accelerated terminal emulator
    miseUniversal runtime version manager (replaces nvm, pyenv, sdkman)
    GNU StowSymlink manager — deploys everything with stow .
    Monaspace Nerd FontCoding font with ligatures and dev icons, bundled in the repo
    Catppuccin MochaConsistent color theme across every single tool

    Currently macOS-first — Linux support is coming, most of it already works.


    ## The Philosophy: One Source of Truth

    The biggest mistake in most dotfiles setups is duplication. You configure your
    LSP server in one file, its formatter in another, its linter somewhere else —
    and when you want to add Go support, you touch six different files and miss
    something.

    This setup has a single file that owns every language decision:
    lua/config/languages.lua.

    typescript = {
      lsp = "vtsls",
      formatters = {
        "prettier"
      },
      linters = {
        "eslint_d"
      },
      filetypes = {
        "javascript",
        "javascriptreact",
        "typescript",
        "typescriptreact"
      },
      lsp_config = {
        settings = {
          typescript = {
            inlayHints = {
              includeInlayParameterNameHints = "all",
              includeInlayVariableTypeHints = true,
            },
          },
        },
      },
    },
    

    Add one entry here and you get: Mason auto-installs the language server and
    formatter, conform.nvim knows how to format on save, nvim-lint runs the right
    linter, and nvim-lspconfig gets the correct settings. Zero other files to touch.

    That’s the design goal throughout — each tool reads from the same source,
    nothing is repeated.


    Neovim: A Real IDE, Not a Text Editor

    This is the centerpiece. Neovim 0.11 introduced a native LSP API
    (vim.lsp.config / vim.lsp.enable) that replaces a lot of boilerplate.
    Combined with lazy.nvim for plugin management, the result is a startup that
    feels instant.

    What’s running under the hood

    Completion (nvim-cmp) pulls from four sources in priority order:
    GitHub Copilot → LSP → LuaSnip snippets → path completions. The popup is
    narrow and intentional — no wall of noise.

    Formatting (conform.nvim) runs on save, per language, with fallback to
    the LSP formatter if a standalone tool isn’t available. The formatter list
    is — you guessed it — pulled from languages.lua.

    Linting (nvim-lint) runs on write, on buffer read, and on insert-leave.
    Diagnostics use a clean inline dot prefix (●) rather than verbose inline text.

    Debugging (nvim-dap) supports Python, Go, C/C++, JavaScript/TypeScript,
    Bash, and Java — all pre-configured with the right adapters and keymaps out
    of the box.

    Git lives in two plugins that complement each other: vim-fugitive for
    staging, committing, pushing, and blaming in a full-screen git buffer;
    gitsigns for per-hunk staging, resetting, and inline blame in the statusline.

    File navigation uses both neo-tree (sidebar tree view) and oil.nvim
    (edit files like a buffer — rename, move, delete by just editing the text).
    Telescope handles fuzzy-finding files, grep across the entire project, and
    browsing help tags.

    The Space leader

    Every keymap uses Space as the leader. Groups are organized by intent:

    • c — code (LSP: go to definition, rename, code action)
    • f — find (Telescope)
    • g — git (fugitive + gitsigns)
    • d — debug (DAP)
    • b — buffer (navigation, close, jump by number)
    • ai — AI (CopilotChat: explain, fix, generate tests) which-key shows you what’s available after pressing the leader — so there’s
      nothing to memorize. You discover it as you go.

    Tmux: Your Sessions Are Sacred

    Most people lose everything when they close a terminal. With tmux-resurrect,
    your sessions — every window, every pane, every working directory — survive a
    reboot.

    The config keeps it minimal:

    • Catppuccin Mocha statusline showing the app name, current session, working
      directory, and CPU usage.
    • Vim-style pane navigation with hjkl — no reaching for arrow keys.
    • Split panes that inherit the current path — open a new split in the same
      project, not in ~.
    • Mouse support — for those moments when you just want to scroll. One thing worth calling out: catppuccin v2.x requires its config options to be
      set before the plugin is sourced. A subtle ordering issue that breaks a lot of
      setups. This one gets it right.

    Zsh: A Shell That Stays Out of Your Way

    The shell config is intentionally lean. Three oh-my-zsh plugins:

    • git — a library of git aliases and prompt info
    • sudo — double-press Esc to prepend sudo to the last command
    • vi-mode — navigate and edit commands with vim motions Two shell enhancers loaded from Homebrew (with existence guards so a missing
      package never breaks a new shell session):
    • zsh-autosuggestions — grayed-out completions from your history as you type,
      accepted with the right arrow
    • zsh-syntax-highlighting — commands turn green when valid, red when not $EDITOR and $VISUAL are both set to nvim, so git commits, crontabs, and
      anything else that opens a text editor get Neovim — not whatever vi resolves
      to on a fresh machine.

    mise: One Version Manager to Rule Them All

    nvm, pyenv, rbenv, sdkman, goenv — each one a different install
    process, a different shell hook, a different mental model. mise replaces all
    of them with a single tool and a unified config format.

    mise install node@lts python@latest java@21 go@latest
    mise use –global node@lts python@latest java@21 go@latest

    It activates via a shell hook in .zshrc and is transparent once set up.
    No more “which node am I on?” moments.


    Alacritty: The Terminal That Gets Out of Your Way

    Alacritty is a GPU-rendered terminal that does very little intentionally.
    No tabs, no built-in multiplexing — tmux handles that. What Alacritty gives
    you is speed, a clean Catppuccin Mocha color palette, a blinking block cursor,
    and Monaspace rendering with comfortable padding.

    Font configuration uses two Monaspace variants: MonaspiceNe for regular and
    bold, MonaspiceRn for italic — a deliberate mix that uses Monaspace’s
    different stroke styles to visually separate code types.


    GNU Stow: The Glue That Holds It Together

    All of this would be useless if deploying it was a chore. GNU Stow solves that
    elegantly.

    Stow treats the dotfiles repo as a “package” and mirrors its structure into
    your home directory as symlinks. Running stow . from inside ~/dotfiles
    creates:

    ~/.zshrc → ~/dotfiles/.zshrc
    ~/.tmux.conf → ~/dotfiles/.tmux.conf
    ~/.config/nvim/ → ~/dotfiles/.config/nvim/
    ~/.config/alacritty/ → ~/dotfiles/.config/alacritty/

    Every edit you make to your config is already in the repo — no copying, no
    syncing. git commit and you’re done.

    A .stow-global-ignore file excludes things that shouldn’t be symlinked:
    the .git folder, the README, shell scripts, and per-machine configs like
    the Copilot auth cache.


    The Color System: Catppuccin Mocha Everywhere

    Context switching between a dark terminal and a light editor — or worse, three
    different accent colors — introduces subtle cognitive friction. You don’t notice
    it, but it’s there.

    Catppuccin Mocha is a warm, low-contrast dark theme with well-differentiated
    accent colors. It has official integrations for every tool in this stack:
    Neovim, tmux, Alacritty, lazygit, even the browser. When your editor, your
    shell, your file tree, your git diff viewer, and your terminal chrome all share
    the same palette, your environment fades into the background and lets the code
    take center stage.


    Who This Is For

    This setup is built for developers who:

    • Write across multiple languages and don’t want to re-configure for each one
    • Want IDE features without an Electron app eating their RAM
    • Care about reproducibility — set up a new machine in minutes, not days
    • Prefer keyboard-driven workflows where the mouse is optional
    • Want AI assistance built in, not bolted on as an afterthought It’s opinionated. It uses Neovim, not VS Code. Tmux, not a terminal’s built-in
      tabs. Zsh, not fish. If that’s not your stack, most of the ideas — especially
      the centralized language config and the Stow deployment model — translate to
      any editor or shell.

    Get It

    git clone https://github.com/abdielreyes/dotfiles.git ~/dotfiles
    cd ~/dotfiles
    stow .

    Full setup instructions, keymaps, and customization guide are in the README.

    The config is macOS-first right now. Linux support is on the roadmap — the
    Neovim and tmux configs are already fully cross-platform. Only the Homebrew
    paths in .zshrc and the font install step need adjustment.


    If you found this useful or have questions about any part of the setup, reach
    out. Configuration is a craft — always improving.


    Link to the repo

  • Hello world!

    This is my first post. Here I will post my notes, projects, hobbies, ideas and more.

    Hope see you soon.