Customization#
The pieces every modern editor leans on: language servers, syntax engines, plugins, themes, AI assistants, and how to manage the resulting config.
Most modern editors (VS Code, Neovim, Helix, Zed, Sublime, Cursor, JetBrains) converged on the same underlying components. The editor chooses the interface; LSP and friends do the work.
Language Server Protocol (LSP)#
LSP is the industry-standard protocol for editor / language-tool integration. Microsoft proposed it for VS Code; every editor that matters now speaks it. The result is one language-server implementation per language, reused across every editor.
What LSP provides:
Diagnostics (errors, warnings).
Hover (type information).
Goto definition / declaration / type / implementation.
Find references.
Rename symbol.
Code completion.
Code actions / quick fixes.
Format document / range.
Document symbols / outline.
Workspace symbol search.
Inlay hints.
Semantic tokens.
Common language servers:
gopls, Go.
rust-analyzer, Rust.
pyright / basedpyright / pylsp, Python.
typescript-language-server, TypeScript / JavaScript.
clangd, C / C++.
lua-language-server, Lua.
bash-language-server, Bash.
ruby-lsp, Ruby.
gradle-language-server, kotlin-language-server, etc.
The editor handles the chrome; the language server does the language work.
Tree-sitter#
Tree-sitter is an incremental parser generator that lets editors maintain an accurate syntax tree of every file as you type. Every modern editor uses it (or its derivatives) for the things that regex-based highlighting and folding never quite got right:
Syntax-aware highlighting (better than regex-based highlighting).
Code folding by syntax.
Selection by syntactic node.
Structural search and replace.
Editors with first-class Tree-sitter: Neovim, Helix, Zed, Atom (legacy), Cursor (via VS Code), Sublime Text 4.
DAP (Debug Adapter Protocol)#
LSP for debuggers. Same idea: the editor speaks one protocol; per-language adapters implement it. Breakpoints, watchpoints, stepping, and variable inspection all become editor-agnostic features that work the same way across every supported language.
Editors with built-in DAP: Helix, Neovim (via nvim-dap), VS Code
(originated DAP), Zed, JetBrains (uses its own internally).
Plugin Ecosystems#
Each editor has its own plugin language and convention. The “right” choice is whichever lets the community keep up; in practice, the editors with the largest plugin catalogs (VS Code, Neovim, Emacs) also have the most active plugin authors.
Editor |
Plugin language / format |
|---|---|
Vim |
Vimscript / Vim9script |
Neovim |
Lua (and Vimscript) |
Emacs |
Emacs Lisp |
Helix |
(none yet; in development) |
Kakoune |
Kakoune script + shell-out |
VS Code / Cursor |
TypeScript / JavaScript |
Zed |
WebAssembly + Tree-sitter for syntaxes |
Sublime Text |
Python |
JetBrains |
Java / Kotlin |
The “right” plugin language is whichever lets the community keep up.
Themes#
Most modern editors share the same theme conventions, light / dark / high-contrast variants, system-preference detection, and patched fonts with programming ligatures and icon glyphs. The themes that pay off best are the ones available across every editor you actually use:
Light vs. dark, most modern editors honor system preference.
High-contrast / dyslexia-friendly options where available.
Patched fonts with programming ligatures and icon glyphs, FiraCode, JetBrainsMono, Iosevka, Hack, Cascadia Code (often “Nerd Font” variants).
Themes that travel well across editors:
Catppuccin, ports for nearly every editor.
Tokyo Night, ditto.
One Dark / One Light (originally Atom).
Solarized, venerable.
Gruvbox / Everforest / Kanagawa / Rose Pine, popular dark themes.
Nord, minimalist dark palette.
Pick one and stop fiddling; they’re nearly all good.
Formatters and Linters#
Most modern editors integrate formatters and linters separately from the LSP, often via a thin adapter plugin per ecosystem. The operator best practice is “format on save, lint on save, delegate hard decisions to the formatter” so the editor never sits on debatable style choices:
Conform.nvim, null-ls, none-ls for Neovim.
prettier, eslint integrations everywhere.
black, ruff, isort for Python.
rustfmt, gofmt, goimports built into the language ecosystems.
Best practice: format on save; lint on save with quick-fix shortcuts; delegate hard decisions to the formatter.
AI Assistance#
A new mandatory category as of 2025-2026. Every major editor either ships AI assistance built in or has a plugin for it; the question is which provider, which model, and how aggressively the assistant edits files on your behalf:
Tool |
Notes |
|---|---|
GitHub Copilot |
First mover; works in VS Code, Neovim, JetBrains, Vim |
Cursor |
VS Code fork built around AI; agentic edits |
Codeium / Windsurf |
Free tier; many editors; Windsurf is a Cursor competitor |
Continue |
Open-source VS Code extension; bring-your-own-model |
Zed AI |
Built-in; bring-your-own-key |
JetBrains AI Assistant |
Official paid integration |
TabNine |
Long-running; supports local models |
Ollama / OpenRouter |
Bring-your-own model providers (local or proxied) |
Claude Code / aider / Plandex |
Terminal-based agentic coding |
Choose by:
Where your code lives (private, regulated, or public).
What models you trust.
Whether you need local-only (Ollama) or cloud is fine.
How agentic you want it, inline completion vs. multi-file edits vs. full agent loops.
Multi-Cursor / Selection#
Multi-cursor editing is now table stakes; every editor on this list ships some form of it, the bindings are mostly the same, and the productivity payoff for find-and-edit-many-callsites is immediate. Common bindings:
Editor |
Add cursor at next match |
|---|---|
VS Code / Cursor / Zed |
Ctrl-D |
Sublime Text |
Ctrl-D |
Neovim (via plugin) |
|
Helix |
|
Kakoune |
|
JetBrains |
Alt-J |
Emacs |
|
Dotfiles#
Manage editor config in a Git repo so it travels between machines. The tools below all do the same job; they differ on templating, secrets handling, and how much they hide the underlying Git operations from you:
chezmoi, declarative, supports templating per host / OS / user; the popular choice in 2026.
yadm, Git wrapper that uses
$HOMEas the work tree.dotbot, YAML-driven installer.
GNU Stow, symlink farm.
Patterns:
Per-machine
.localoverrides sourced from main config.Templated values for hostnames, work-vs-personal differences.
Bootstrap script (
./install.sh) to set up everything fresh.
Settings Sync#
Most modern editors ship account-based settings sync as a built-in alternative to dotfile management. Whichever path you pick, the goal is the same: a fresh machine with a working environment in five minutes.
VS Code / Cursor, settings sync via Microsoft / GitHub account.
JetBrains, IDE settings sync via JetBrains account.
Zed, account-based sync.
Neovim / Vim / Emacs, dotfiles in Git.
Pick whatever causes the least friction; the goal is “fresh machine, working environment in 5 minutes”.
Editor-Agnostic Tools#
A handful of tools span every editor and pay back many times over. These work the same way regardless of which editor you launch, so adopting them once makes the operator’s environment portable across whatever editor a future project demands:
direnv, per-directory environment variables.
pre-commit, run linters / formatters at commit time, regardless of editor.
EditorConfig,
.editorconfigfile for per-project indentation / line endings; honored by every major editor.commitlint, enforce conventional commits.
Tree-sitter playground, explore parse trees.
The editor is yours; the tooling around it is shared.