Configuring Neovim, "How to run non-nix executables?"

Hey there I am having trouble with setting up the Neovim plugin mason-lspconfig.nvim.

I am following a tutorial series by “Typecraft” for setting up NeoVim, and I am stuck figuring out how to get the LSP working properly:

When I add an LSP server such as:
ensure_installed = {"lua_ls"},

The system prompts with the error:
[ERROR][2024-07-24 23:44:44] .../vim/lsp/rpc.lua:770 "rpc" "/home/technicus/.local/share/nvim/mason/bin/lua-language-server" "stderr" "Could not start dynamically linked executable: /home/technicus/.local/share/nvim/mason/packages/lua-language-server/libexec/bin/lua-language-server\nNixOS cannot run dynamically linked executables intended for generic\nlinux environments out of the box. For more information, see:\nhttps://nix.dev/permalink/stub-ld\n"

While trying to figure out why I learned:
“NixOS cannot run dynamically linked executables intended for generic Linux environments out of the box. This is because, by design, it does not have a global library path, nor does it follow the Filesystem Hierarchy Standard (FHS).” → How to run non-nix executables?

Then I found the package lua-language-server and added it to the NixOS config:
environment.systemPackages = [ pkgs.lua-language-server ];

The NeoVim plugin mason-lspconfig.nvim works after adding lua-language-server to the Nix config.

Then I add more LSP servers in the Neovim config to see what would happen:
ensure_installed = {"lua_ls", "jsonls", "jsonnet_ls", "biome"},

The result is more errors for what appears to be the same reason as before:
[ERROR Thu 25 Jul 2024 11:50:10 AM CDT] ...e/nvim/lazy/mason.nvim/lua/mason-core/installer/init.lua:249: Installation failed for Package(name=biome) error=spawn: npm failed with exit code - and signal -. npm is not executable

I am having trouble finding the language server packages to add in the NixOS config, and this is not the seamless solution the plugin is designed for.

The plugin has an option: auto_install = true, which allows the plugin to install whatever LSP there is that supports the language without any additional intervention, which is dynamic and ideal.

The ultimate solution for this extra layer of abstraction would not require me to look up the package and install it in the NixOS config, and I could natively install the LSPs and any other plugin without additional steps.

– I am following the typecraft guide.
– What is “The Ultimate Solution”?
– How do I implement it?
– Do I need to have a fundamentally different mindset and strategy for setting this up?
– Thanks for your recommendations, guidance, advice, suggestion, assistance, and help.

You probably will have better results with a Nix-native plugin management solution, like GitHub - nix-community/nixvim: Configure Neovim with Nix! [maintainer=@GaetanLepage, @traxys, @mattsturgeon]. Making other package managers (such as mason.nvim) work on NixOS is often a chore.

If for some reason you absolutely must obey some meme video when setting up your computer, GitHub - Mic92/nix-ld: Run unpatched dynamic binaries on NixOS might be of interest. That’s a system-wide aberration modification that makes the entire point of running NixOS optional programs that you download automatically reference some hopefully-compatible path in the Nix store. It mostly works. (It’s actually pretty cool that it does work as well as it does; I’m horrified by the idea that someone would use it in production but also impressed by the folks who made it happen.)

5 Likes

to be clear, there’s no need to use nixvim. home-manager.neovim.plugins coupled with typical non-lazy lua config does the job

2 Likes

It sure does; I use pure Home Manager myself. But OP seemed interested in a very hands-clean solution—add things to a list in one place, boom, done—and I think nixvim is better at providing that once you’re talking about plugins depending on language servers and so on.

Plus not everyone is into Home Manager, and nixvim works with or without it.

1 Like

Uggahaa . . . . I don’t understand anymore . . . . so many different ways to do the same thing.

I am new to NixOS by the way, and trying to setup Neovim makes me want to go back to Arch Linux.

What about setting up Neovim as a development environment?

don’t use lazy, mason and alike, install things with nix instead. me and @rhendric gave you two relatively simple ways to do that: home-manager or nixvim. the former is a simpler approach, the latter is more complex (not necessarily in terms of usage, but complexity of the solution itself) and can be quite limiting. you choose whatever you like more (i’d advise the home-manager way tho)

well, this is how programming works, yes

After a day of trying to setup Neovim I got a little fried.

Coming to NixOS, I was anticipating to encounter a unified standard method for maintaining the system, but I didn’t realize it was so fragmented.

Now I understand there are so many different methodologies integrated into the NixOS ecosystem, each with their own (dis)advantages and the like.

This has lead me to understand that so long as a chosen method “complies with the non-compliance to file-system hierarchy standard clause” how I set up the system is purely a matter of – so long as it works, configuration options are strictly a matter of preference.

Let me know If I miss out on any possible methods for installing and configuring software within NixOS in this list:

  1. [ nix-env ]
  2. [ NixOS Configuration ]
  3. [ nix-shell ]
  4. [ flakes ]
  5. [ home-manager ]
  6. [ nix-flatpak ]
  7. [ declarative-flatpak ]
  8. [ channels ]

Are any of these methodologies dependent on any other or incompatible together?

Also if you would offer the consideration to correct any misinterpretations in the explanation of my apparent understand.

I see a lot of mention about how some of these methods are “experimental” but commonly supported . . . maybe help clarify this for me as well.

NixOS seems kind of like a prime candidate as the foundational subject for a doctoral thesis in computer science.

Oh – of course it is the center piece of a nix-thesis!

Ha ha, yeah, welcome to the scrum!

Many of the things in that list are not the same kind of thing. It’s like this being a list of possible methods for cooking food:

  1. [ Oven ]
  2. [ Microwave oven ]
  3. [ Plate ]
  4. [ Refrigerator ]
  5. [ DoorDash ]
  6. [ Reverse osmosis water filter ]
  7. [ Pizza ]
  8. [ Melon baller ]

You’ll figure it out; there are a lot of things you can do in a kitchen, but focus on one recipe at a time, ignore the things you don’t need, and you’ll build up skill gradually.

If you have questions about a specific tool in the Nix kitchen, that’d be easier to answer than a full inventory of everything a well-stocked kitchen might contain.

3 Likes

With nixvim how do I open a file from the terminal with nix run as I would with nvim path/file.ext?

I installed it with nix flake init --template github:nix-community/nixvim.

How can I put nixvim into a path that allows me to call it from anywhere within the directory tree?

What your’re doing now is running NixVim as standalone, but to integrate it as part of your system, you must follow the steps in the installation section.

With that, NixVim will replace the nvim command and you can just nvim path/file.ext

1 Like

Alright, I have made some progress.

I am now trying to configure the “neo-tree” plugin.

The previous configuration I setup with “lazy” I was able to assign a keybinding with the following:

return {
	"nvim-neo-tree/neo-tree.nvim",
	branch = "v3.x",
	dependencies = {
		"nvim-lua/plenary.nvim",
		"nvim-tree/nvim-web-devicons",
		"MunifTanjim/nui.nvim",
	},
	config = function()
		vim.keymap.set("n", "<C-n>", ":Neotree filesystem reveal left<CR>", {})
		vim.keymap.set("n", "<leader>bf", ":Neotree buffers reveal float<CR>", {})
	end,
}

With the standalone installation, I am trying to write the keybinding with:

{
  # Buffer bar
  plugins.neo-tree = {
    enable = true;
    enableDiagnostics = true;
    enableGitStatus = true;
    enableModifiedMarkers = true;
    enableRefreshOnWrite = true;
    closeIfLastWindow = true;
    popupBorderStyle = "rounded"; # Type: null or one of “NC”, “double”, “none”, “rounded”, “shadow”, “single”, “solid” or raw lua code
    buffers = {
      bindToCwd = false;
      followCurrentFile = {
        enabled = true;
      };
    };
    window = {
      width = 40;
      height = 15;
      autoExpandWidth = false;
      mappings = {
        "<space>" = "none";
        "<C-n>" = ":Neotree filesystem reveal left<CR>";
      };
    };
  };
}

This does not work.

I have reviewed the keymap documentation, but I do not understand it and the examples are unclear to me.

What is the proper way to write the keymap?

Well, those are two different things:

  • programs.nixvim.keymaps: available in the whole program
  • programs.nixvim.plugins.neo-tree.window.mappings: for the neo-tree window

In this case, you need:

  programs.nixvim.keymaps = [
    {
      key = "<C-n>";
      action = ":Neotree filesystem reveal left<CR>";
    }
    {
      key = "<C-b>";
      action = ":Neotree buffers reveal float<CR>";
    }
  ];

And in neo-tree, let’s say I want to change how I open files or any :h neo-tree-mappings:

  programs.nixvim.plugins.neo-tree.window.mappings = {
    h = "open_tabnew";
    l = "open";
  };

Why do these config options:

    {
      mode = "n";
      key = "h";
      action = ":Neotree open_tabnew<CR>";
    }
    {
      mode = "n";
      key = "l";
      action = ":Neotree open<CR>";
    }

return this error:

E5108: Error executing lua ...ages/start/neo-tree.nvim/lua/neo-tree/command/parser.lua:173: ...ages/start/neo-tree.nvim/lua/neo-tree/co
mmand/parser.lua:151: Invalid argument: open_tabnew                                                                                    
stack traceback:                                                                                                                       
        [C]: in function 'error'                                                                                                       
        ...ages/start/neo-tree.nvim/lua/neo-tree/command/parser.lua:173: in function 'parse'                                           
        ...ckages/start/neo-tree.nvim/lua/neo-tree/command/init.lua:169: in function '_command'                                        
        [string ":lua"]:1: in main chunk   

Because Neotree open_tabnew and Neotree open are not proper commands. See :h neo-tree-commands