Matt Novak logo Matt Novak

Blog

Why I'll Always Be a Neovim Person (and Probably Never an IDE Guy)

2025-09-15 • 5 min
neovim vim terminal workflow editor gentoo

Why I'll Always Be a Neovim Person (and Probably Never an IDE Guy)🔗

I live in the terminal. It's where my hands make sense of ideas, where projects grow from a blank buffer into something useful. Over the years I've flirted with big IDEs—clicked through their wizards, tried their code maps, watched progress bars promise productivity. But every time, I end up right back in Neovim, a few panes of tmux, and a stack of tiny, sharp CLI tools. Maybe it's Gentoo. Maybe it's me. Probably it's both.

The Terminal Is My Native Habitat🔗

I'm faster when I don't leave the keyboard. Modal editing, muscle memory, and composable commands let me think in verbs instead of menus:

  • jump → change → test → log → commit → push
  • / to find, . to repeat, ci" to reshape, :%s// to refactor
  • rg to discover, jq to slice, fzf to jump, gh to review

Neovim is the hinge that lets all of that swing together. It's not a monolith; it's a router for intent. I can pipe, map, and compose without fighting a "project model" I didn't ask for.

Gentoo Shaped My Taste🔗

Gentoo rewards intent and punishes hand-waving. You decide what gets compiled, what features exist, and why. That philosophy bleeds into my editor: I want primitives that are visible and controllable, not opaque magic. Neovim aligns with that:

  • Minimal core, deliberate extensions. I choose LSP, Treesitter, formatter, linter—each on purpose.
  • Performance you can feel. Startup in milliseconds, instant search, no mystery pauses.
  • Predictable environment. If it runs in a terminal on Gentoo, it runs everywhere I care about (including over SSH).

My Daily Workflow (Fast, Boring, Effective)🔗

  • Session: tmux new -s work → left pane: nvim, right pane: just test -w or cargo watch -x test / air / uv run.
  • Navigation: Telescope over ripgrep + fd (<leader>ff, <leader>fg, <leader>fb), plus harpoon for rapid hopping between "current working set" files.
  • Editing: Treesitter text objects, LSP code actions on tap, null-ls/conform.nvim to format on save.
  • Git: :G/fugitive + diffview.nvim to stage hunks with intention; git delta for readable diffs.
  • Jump to definition / references: LSP does it cleanly without the IDE overhead. I get hover docs, rename, code actions—all with keybinds I remember.
  • Diagnostics: Native LSP diagnostics with virtual text off (I like them in a separate list), trouble.nvim for quick triage.
  • Debugging: nvim-dap when I need it, not a background service that's always slurping CPU.

Here's the tiny backbone that gets me 90% of the way there:

-- lua/plugins.lua (lazy.nvim)
return {
  { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate" },
  { "neovim/nvim-lspconfig" },
  { "williamboman/mason.nvim", config = true },
  { "williamboman/mason-lspconfig.nvim" },
  { "j-hui/fidget.nvim", tag = "legacy" },       -- LSP progress
  { "nvim-lua/plenary.nvim" },
  { "nvim-telescope/telescope.nvim" },
  { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
  { "lewis6991/gitsigns.nvim" },
  { "tpope/vim-fugitive" },
  { "numToStr/Comment.nvim", config = true },
  { "windwp/nvim-autopairs", config = true },
  { "folke/trouble.nvim" },
  { "stevearc/conform.nvim" },                   -- formatter
  { "ThePrimeagen/harpoon" },
}

And a few opinionated keymaps that keep my brain smooth:

-- lua/keymaps.lua
local map = vim.keymap.set
map("n", "<leader>ff", "<cmd>Telescope find_files<cr>", { desc = "Files" })
map("n", "<leader>fg", "<cmd>Telescope live_grep<cr>",  { desc = "Grep" })
map("n", "<leader>fb", "<cmd>Telescope buffers<cr>",    { desc = "Buffers" })
map("n", "<leader>e",  "<cmd>copen<cr>",                { desc = "Quickfix open" })
map("n", "<leader>q",  "<cmd>cclose<cr>",               { desc = "Quickfix close" })
map("n", "<leader>ca", vim.lsp.buf.code_action,         { desc = "Code action" })
map("n", "gd",         vim.lsp.buf.definition,          { desc = "Go to def" })
map("n", "gr",         vim.lsp.buf.references,          { desc = "Refs" })

Minimal config, maximal payoff.

Why Big IDEs Don't Stick (For Me)🔗

I don't hate IDEs. They're incredible for people who want batteries included. But here's why they keep bouncing off my brain:

  • Context switching. Leaving the terminal breaks flow. I don't want to reach for a mouse or dig through panes that aren't mine.
  • Hidden state. Indexers, caches, project files—things drift. I prefer explicit, text-based config in my dotfiles and project scripts.
  • Footprint. My editor shouldn't need a background daemon to type a brace. Neovim plus a few binaries is lean, transparent, and SSH-friendly.
  • Portability. My setup follows me everywhere in a handful of files. No "install the IDE, then the plugins, then…" ritual.

"But What About…?" (Refactoring, IntelliSense, Debugging)🔗

Neovim does it well enough—and often better—without the weight:

  • IntelliSense & navigation: Native LSP covers Rust, Go, Python, JS/TS, etc. Mason bootstraps servers on demand.
  • Refactoring: LSP rename + Treesitter motions handle 90%. For the rest, structural search or tool-specific refactors (Rust analyzer, go fix, ruff, black, stylua) keep me honest.
  • Debugging: nvim-dap when needed; otherwise logs, dbg!, println!, -run/-test.v—fast feedback beats heavy tooling for most day-to-day bugs.

Composability Beats Features🔗

The best tools interlock. Neovim + tmux + ripgrep + fd + fzf + just/Make + language tooling gives me a custom IDE that scales with the project, not against it. When I need to swap a piece, I swap a piece. No vendor lock-in, no UI rewiring.

Minimal Apps, Maximum Throughput🔗

Gentoo nudged me toward a bias: fewer moving parts, deeper mastery. I keep a slim set of apps and lean on the terminal for everything else. That's not asceticism; it's a performance choice. Less chrome, more content.

If You Want to Try This Style🔗

  • Start with plain Neovim. Add LSP, Treesitter, Telescope. Stop.
  • Learn motions and text objects until they're reflex.
  • Wire up just or Make so :terminal just test runs your world.
  • Keep configs small. If a plugin doesn't earn its keep in a week, drop it.

A tiny justfile I use a lot🔗

# justfile
test:       # run tests
    cargo test --all --quiet

watch:      # run tests on change
    cargo watch -x test

lint:
    ruff check .
    ruff format --check .

fmt:
    ruff format .
    stylua **/*.lua

Now the editor and the project speak the same verbs.


I'll always be a Neovim person because it lets me work the way I think: small tools, tight feedback, no ceremony. IDEs are fine cathedrals. I just prefer workshops—well-lit, a little noisy, everything within reach. And, yeah, maybe that's the Gentoo talking.

AI-assisted writing

I draft and edit all articles myself, and I use AI as an assistant for outlining, phrasing, and cleanup. Curious how I use it—and where I draw the lines?