Using a nix shell breaks LSP in Neovim?

I’m trying to develop a Rust application, however, when I develop from within the Nix shell for my project (via. nix develop), my LSP within Neovim appears to sort-of break:

I’ve confirmed it works fine outside of the nix shell:

Is there any way to either:

  • Fix the issue so that the LSP from the development shell works fine; or
  • Use the system LSP from within the shell.

For reference, I’m using the oxalica/rust-overlay to provide the latest stable toolchain and my default dev shell is:

# ...
        devShells = {
          # Default development shell
          default = pkgs.mkShell {
            inherit buildInputs;
            nativeBuildInputs = [
              toolchain
            ];
            RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library";
          };
# ...

I’ve tried to find an answer to this, and all I could find was Proper way to run a language server in a nix-shell with neovim lspconfig - #2 by anon23399578, which I don’t think solves my issue as it looks like I’d have to set the rust-analyzer location for each and every project whenever I switch between them.

How are you installing rust analyzer?

Am I supposed to declare rust-analyzer as a build input explicitly when using oxalica/rust-overlay? I was assuming the toolchain would include it and it seems that manually declaring rust-analyzer doesn’t change the outcome. If this helps:

# ...
        overlays = [(import rust-overlay)];
        pkgs = import nixpkgs {
          inherit system overlays;
        };

        # Toolchain for development use
        toolchain = pkgs.rust-bin.stable.latest.default;
        naersk' = naersk.lib.${system}.override {
          cargo = toolchain;
          rustc = toolchain;
        };
# ...

I always make sure to use a RA that is from the same source of the compiler.

If I use a nixpkgs compiler, I make sure to use RA from nixpkgs.

If I use it from oxalica, I make sure to use a toolchain that has RA enabled. It’s not in the default chain.

Ah, that would make sense.

How can I enable rust-analyzer for my toolchain then? Using complete is obviously a bad idea, and the oxalica/rust-overlay docs don’t specifically mention it.

You override it with extensions being set to a list of components you want to have in addition.

Something like toolchain = pkgs.rust-bin.stable.latest.default.override { extensions = "rust-analyzer"; }

1 Like

I’ve added the following:

# ...
        # Toolchain for development use
        toolchain = pkgs.rust-bin.stable.latest.default.override {
          extensions = ["rust-analyzer"];
        };
# ...

And confirmed via. :checkhealth vim.lsp that it is using /nix/store/vb0iyfnnjg4npvlib0yxvi9d5rvq8mss-rust-default-1.93.0/bin/rust-analyzer and not my system one. However, the problem persists.

Edit: Checked the rust-analyzer logs, turns out it was missing the rust-src component. This configuration works:

# ...
        # Toolchain for development use
        toolchain = pkgs.rust-bin.stable.latest.default.override {
          extensions = ["rust-analyzer" "rust-src"];
        };
# ...