Editors
Editors
Multi-editor setup supporting VS Code family, Neovim, Emacs, JetBrains, Zed, and Positron.
Architecture
Module Layout
modules/editors/
default.nix Shared options, common extensions, common settings
vscode.nix Visual Studio Code
cursor.nix Cursor AI Editor (VS Code fork)
kiro.nix Kiro IDE (VS Code fork, AWS)
antigravity.nix Antigravity (VS Code fork)
vim.nix Neovim
emacs.nix Emacs + Doom Emacs
jetbrains.nix JetBrains IDE family
positron.nix Positron (data science)
zed.nix Zed Editor
VS Code Family Extension Sharing
VS Code, Cursor, Kiro, and Antigravity share a single extension list via
modules.editors.vscode.commonExtensions defined in default.nix. Each editor
only adds its own unique extensions on top (if any). This eliminates 4x duplication.
default.nix ──► commonExtensions ──┬──► vscode.nix (uses directly)
├──► cursor.nix (uses directly)
├──► kiro.nix (uses directly)
└──► antigravity.nix (uses directly)
Settings are similarly shared via modules.editors.vscode.commonSettings.
Extension Source: nix-vscode-extensions
All extensions come from nix-vscode-extensions,
a community flake that caches ~80,000 extensions from the VS Code Marketplace and Open VSX,
updated daily via GitHub Actions. This replaces nixpkgs’ built-in pkgs.vscode-extensions
(only ~456 extensions, many outdated).
Source attrset: vscode-marketplace-release — release-only, platform-specific
extensions. Individual extensions with version constraints (e.g. vadimcn.vscode-lldb)
fall back to vscode-marketplace-release-universal.
Overlay: Applied via nixpkgs.overlays in modules/editors/default.nix, following
the same pattern as modules/dev/rust.nix. This keeps the overlay self-contained with
the module and ensures extensions inherit the system’s allowUnfree = true config:
# modules/editors/default.nix
{
nixpkgs.overlays = [
hey.inputs.nix-vscode-extensions.overlays.default
];
}
Unfree extensions: Marketplace extensions are marked unfree by
buildVscodeMarketplaceExtension. Using the system overlay (instead of accessing
the flake input directly via hey.inputs) ensures they inherit the system nixpkgs’
allowUnfree = true — otherwise pure evaluation fails with “Refusing to evaluate
package because it has an unfree license.”
Extension Categories
AI Coding Agents
| Extension | Editor | Description |
|---|---|---|
anthropic.claude-code | VS Code family | Claude Code by Anthropic |
openai.chatgpt | VS Code family | ChatGPT by OpenAI |
google.geminicodeassist | VS Code family | Gemini Code Assist |
google.colab | VS Code family | Google Colab integration |
qwenlm.qwen-code-vscode-ide-companion | VS Code family | Qwen Code IDE companion |
copilot-lua + copilot-cmp | Neovim | GitHub Copilot (via astrocommunity) |
Programming Languages
| Language | VS Code Extension | Neovim LSP | Neovim Formatter |
|---|---|---|---|
| Python | ms-python.python, ms-python.vscode-pylance | pyright, ruff | isort, black |
| Go | golang.go | gopls | gofmt, goimports |
| Rust | rust-lang.rust-analyzer | rust_analyzer | rustfmt |
| C/C++ | ms-vscode.cpptools | clangd | — |
| TypeScript/JS | esbenp.prettier-vscode, dbaeumer.vscode-eslint | ts_ls, eslint | prettierd |
| Java | vscjava.vscode-java-pack | jdtls | google-java-format |
| Kotlin | fwcd.kotlin | kotlin_language_server | ktfmt |
| Ruby | shopify.ruby-lsp | ruby_lsp | rubocop |
| PHP | bmewburn.vscode-intelephense-client | — | — |
| Lua | sumneko.lua | lua_ls | stylua |
| Zig | ziglang.vscode-zig | zls | — |
| Haskell | haskell.haskell | hls | — |
| OCaml | ocamllabs.ocaml-platform | ocamllsp | — |
| Scala | scalameta.metals | — | — |
| Clojure | betterthantomorrow.calva | — | — |
| Elixir | elixir-tools.elixir-tools | — | — |
| Dart/Flutter | dart-code.dart-code, dart-code.flutter | — | — |
| C#/.NET | ms-dotnettools.csdevkit | — | — |
| Nix | jnoortheen.nix-ide, kamadorueda.alejandra | nixd | alejandra |
| Janet | janet-lang.vscode-janet | — | — |
| Julia | julialang.language-julia | — | — |
| PowerShell | ms-vscode.powershell | — | — |
Bioinformatics & Pipelines
| Extension | Description |
|---|---|
snakemake.snakemake-lang | Snakemake workflow language support |
tfehlmann.snakefmt | Snakemake formatter |
nextflow.nextflow | Nextflow DSL support |
File associations (in commonSettings):
*.smk,*.snakefile,Snakefile→ Python (syntax highlighting via treesitter)*.nf,nextflow.config→ Groovy
Neovim filetype detection (in config/nvim/lua/plugins/languages.lua):
filetype = {
extension = { smk = "python", snakefile = "python", nf = "groovy" },
filename = { ["Snakefile"] = "python", ["nextflow.config"] = "groovy" },
},
Data Formats & Config
| Extension | Language |
|---|---|
tamasfe.even-better-toml | TOML |
redhat.vscode-xml | XML |
redhat.vscode-yaml | YAML |
graphql.vscode-graphql | GraphQL |
hashicorp.terraform | HCL/Terraform |
mechatroner.rainbow-csv | CSV/TSV |
DevOps & Infrastructure
| Extension | Tool |
|---|---|
ms-azuretools.vscode-docker | Docker + Podman |
ms-kubernetes-tools.vscode-kubernetes-tools | Kubernetes |
tim-koehler.helm-intellisense | Helm charts |
exiasr.hadolint | Dockerfile linting |
github.vscode-github-actions | GitHub Actions CI/CD |
Database
| Extension | Description |
|---|---|
mttools.sqltools | SQL tools framework |
cweijan.vscode-postgresql-client2 | PostgreSQL client |
Version Control & Code Review
| Extension | Description |
|---|---|
eamodio.gitlens | Git lens (shared across all VS Code family) |
github.vscode-pull-request-github | GitHub PR integration |
octo-nvim | GitHub integration for Neovim |
gitsigns-nvim | Git signs for Neovim |
Debugging
| Editor | Debug Adapters |
|---|---|
| VS Code family | vadimcn.vscode-lldb (Rust/C++), ms-python.debugpy (Python) |
| Neovim | nvim-dap, nvim-dap-ui, nvim-dap-python, nvim-dap-go, delve |
UI & Theme
| Extension | Description |
|---|---|
pkief.material-icon-theme | File icons |
catppuccin.catppuccin-vsc | Catppuccin Mocha theme |
usernamehw.errorlens | Inline error highlighting |
vscodevim.vim | Vim keybindings |
Neovim (vim.nix)
Architecture
AstroNvim v6 + lazy.nvim + Nix-provided LSP tools. See docs/neovim.md for the complete developer guide.
Nix provides: neovim (bare) + 50+ LSP/formatter/linter packages
Config link: config/nvim/ → ~/.config/nvim/ (home.configFile, recursive symlink)
Plugin manager: lazy.nvim (downloads to ~/.local/share/nvim/lazy/)
Framework: AstroNvim v6 (keybindings, UI, LSP, completion)
Completion: blink.cmp (Rust-based, replaces nvim-cmp)
Theme: astrodark (AstroNvim built-in, via astroui.colorscheme)
File explorer: neo-tree.nvim
Fuzzy finder: snacks.nvim (replaces Telescope)
LSP Servers
Configured via astrolsp with native vim.lsp.config:
| Server | Language | Special Config |
|---|---|---|
nixd + nil | Nix | Dual server coverage |
basedpyright | Python | Type checking |
ruff | Python | Linting + formatting |
clangd | C/C++ | UTF-8 offset encoding |
rust_analyzer | Rust | — |
gopls | Go | — |
bashls | Bash, Zsh, Sh | Extended for zsh filetype |
lua_ls | Lua | Neovim runtime awareness |
vtsls | TypeScript/JS | — |
yamlls | YAML | — |
taplo | TOML | — |
terraformls | HCL/Terraform | — |
typos_lsp | All | Typo detection |
zls | Zig | — |
jdtls | Java | — |
kotlin_language_server | Kotlin | — |
ruby_lsp | Ruby | — |
Formatters & Linters (none-ls)
| Tool | Languages | Type |
|---|---|---|
stylua | Lua | Formatter |
prettier | HTML/CSS/JS/TS/JSON/YAML/XML/Markdown | Formatter |
shfmt | Bash, Zsh, Sh | Formatter (2-space indent) |
alejandra + nixfmt | Nix | Formatter |
black + isort | Python | Formatter |
rustfmt | Rust | Formatter |
gofumpt | Go | Formatter |
golangci_lint | Go | Linter |
impl | Go | Code action (interface impl) |
google-java-format | Java | Formatter |
rubocop | Ruby | Formatter + linter |
sql-formatter | SQL | Formatter |
DAP (Debug Adapter Protocol)
nvim-dap+nvim-dap-ui+nvim-dap-virtual-textnvim-dap-python— Python debugging (debugpy)nvim-dap-go— Go debugging (delve)- Keybindings:
F5continue,F10step over,F11step into,F12step out,<Space>bbreakpoint
Keybindings (Custom)
| Key | Action |
|---|---|
<Space><Space> | Find files (snacks.nvim) |
<Space>fw | Live grep (snacks.nvim) |
<Space>* | Grep word under cursor |
<Space>fb | Buffers |
<Space>xx | Toggle diagnostics (Trouble) |
<Space>e | Toggle neo-tree (git status) |
<Space>o | Focus neo-tree |
Tab / Shift+Tab | Next/prev buffer |
gf | Open/create file under cursor |
gd | Go to definition |
gD | Go to declaration |
K | Hover documentation |
gi | Go to implementation |
gr | References |
<Space>rn | Rename symbol |
<Space>ca | Code action |
Ctrl+k | Signature help |
Fake HOME Jailing
All VS Code family editors and JetBrains IDEs use wrapFakeHome or mkWrapper to set HOME to ~/.local/user. This isolates editor state from the real home directory.
- VS Code:
HOME="$XDG_FAKE_HOME" - Cursor/Kiro/Antigravity:
HOME=${config.home.fakeDir} - JetBrains:
wrapFakeHomeper IDE binary - Positron:
mkWrapperwithHOME=fakeDir
Remote SSH servers are configured to install to ~/.local/user/.vscode-server.
Adding New Extensions
To VS Code family editors
Add to modules/editors/default.nix under commonExtensions:
- Nixpkgs extensions: add to the
with pkgs.vscode-extensions; [...]list - Marketplace extensions: add to the
with vscodeExtensionsPkgs.vscode-marketplace; [...]list
To Neovim
- Add a Lua file in
config/nvim/lua/plugins/with the plugin spec (lazy.nvim format) - If it needs an LSP server, add the Nix package to
nvim-lsp-packagesinvim.nix - Reopen Neovim — lazy.nvim auto-installs the plugin
- Commit the updated
lazy-lock.json
Related Modules
| Module | Relationship |
|---|---|
modules/dev/*.nix | Language toolchains (compilers, runtimes, package managers) |
modules/themes/apps.nix | App theming (does not cover editors directly) |
modules/themes/default.nix | Font definitions (vscodeFamily, vscodeTerminalFamily) |
modules/home.nix | Home Manager bridge (home.file, home.configFile) |
modules/persist.nix | Impermanence persistence paths |