Repository navigation
refactor(lsp): default project toolchains off - #51
Merged
Merged
Conversation
Split the language toggles into editor-wide tooling (config, shell, typst: on) and project toolchains (python, c, rust, go, js, haskell, lean: off). A project's language server has to match its own compiler or runtime, so it comes from the project's flake devShell via direnv; lua/plugins/lsp.lua only names the servers and picks up whatever is first on PATH. Installing them globally was mostly redundant, and some (HLS) carry multi-GiB closures that every nixpkgs bump re-downloads. Neovim skips a server whose cmd is not executable (logged to lsp.log, no notification), so opening such a file outside a project shell just runs without that LSP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up to defaulting project toolchains off: those toggles also
carry the per-language formatters and linters, which now come from the
project's devShell too. Make the config treat them like servers:
- conform: notify_no_formatters = false, so a .go/.py/.c buffer outside
a project shell doesn't warn about goimports/black/clang-format.
- none-ls: gate golangci_lint on a runtime_condition, so it is skipped
instead of erroring on spawn when golangci-lint isn't on PATH.
- js back on by default: it is just nodejs, which commitlint already
pulls into the closure, so turning it off saved nothing.
- Fix comments still calling packages.default the every-language build,
and document `.override { enable_<lang> = true; }` for re-enabling.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drop notify_no_formatters = false: it was never needed. Every buffer also gets codespell (formatters_by_ft["*"]), which is always installed, and conform only warns when none of a buffer's formatters are available. A missing goimports/black/clang-format is skipped quietly, and the warning stays for genuinely broken setups (e.g. editor-wide formatters missing). README: explain that per-language toolchains come from the project's devShell via direnv, and how to turn them on without project flakes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
potsrevennil
marked this pull request as ready for review
October 20, 2026 06:51
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
packages.defaultinstalled every language toolchain globally (python, clang, rustup, go + gopls + golangci-lint), and kapi-sysconf additionally turned on haskell and lean. Those tools have to match each project's own compiler, runtime and CI: HLS ↔ GHC, gopls ↔ go, black/clang-format ↔ the versions CI checks with. So a global copy is often the wrong version, and it only gets used when no project shell is active. It is also expensive: nixpkgs' HLS alone is a ~9 GiB closure that every nixpkgs bump re-downloads.Project toolchains (python, c, rust, go, haskell, lean) now default to off. Editor-wide tooling (config, shell, typst, js/nodejs) stays on. Projects provide their server, formatter and linter from their flake devShell, and direnv puts them first on
PATH. The Lua config only names tools, so it picks up whichever binary that is, and it now stays quiet when one is missing:Servers: Neovim 0.12's
can_startskips a config whosecmdisn't executable. It writes a line tolsp.logand shows no notification.Formatters: no change needed. conform skips unavailable formatters, and since
codespell(formatters_by_ft["*"]) is always available it never reaches its "Formatters unavailable" warning.Linters: none-ls
golangci_lintis gated on aruntime_condition, so it is skipped instead of throwing "command golangci-lint is not executable".Look at:
lua/plugins/none-ls.lua. Theruntime_conditionis checked on every run, so it also works ifPATHchanges mid-session (e.g. direnv.vim).Verify:
nix build .#defaultno longer pulls in go, gopls, golangci-lint, python, clang-tools or rustup.packages.liteandpackages.bundleset every toggle explicitly, so CI'sKAPI_VIM_LANGS=shell,gobundle still tests go.Re-enable on a machine without project flakes:
kapi-vim.override { enable_go = true; }, orKAPI_VIM_LANGS=go nix run --impure .#bundle.Docs: README has a new "Language toolchains" section.
Out of scope: a CI fixture that exercises project-provided tools, which we decided wasn't worth the runtime.
🤖 Generated with Claude Code