nix-community / nixvim

Configure Neovim with Nix! [maintainer=@GaetanLepage, @traxys, @mattsturgeon]
https://nix-community.github.io/nixvim
MIT License
1.47k stars 222 forks source link

[Feature Request] Complete programming language support #635

Closed zoedsoupe closed 9 months ago

zoedsoupe commented 9 months ago

Hello! Nice project here! I always build my neovim config with nix and then with flakes and it awesome to see the cimmunity building a “complete” flake with many possibilities for who would like to just set neovim up declaratively.

I would like to start my contributions to this project adding plugins and color schemes but I also would like to know if there’s any plan to implement programming languages support in a declarative way, like an abstraction around plugins opts.

I would work like that:

{
  programs.nixvim = {
    languages.elixir {
      enable = true;
      lsp = {
        enable = true;
        name = “nexts”; # or elixir-ls
        package = next-ls;
      };
      # other configs
    };
    languages.rust.enable = true; # use default options
  };
}

WDYT about this possible feature? I would like to tackle this if there’s chance to evolve in discussion 😊

traxys commented 9 months ago

Nixvim is not really targeted as being a neovim distribution, it's mostly targeted at being a thin wrapper around neovim & neovim plugins. I think the feature you want is something more akin to neovim distrubitions like LunarNvim, LazyNvim and such. This kind of features can be built upon Nixvim, but I don't think it fits in the repo proper

zoedsoupe commented 9 months ago

Ok, if that feature is against the flake philosofy, no problem with that! But I think that is different from being a neovim distribution. My point is: on neovim distributions there are configs pre-defined with a style pre-defined too, for example for buffer line/tree view and other UI plugins. Adding support to a language is different as this project aims to give total control to the user to set up the config. So keymaps would be defined by the user. THis possible feature aims only to be a wrapper into plugins,as if I need to support elixir language one would do:

{
  programs.nixvim = {
    plugins = {
      elixir-ls.enable = true;
      elixir-tools.enable = true;
      treesitter = {
        enable = true;
        ensureInstalled = [“elixir”];
      };
    };
  };
}

Abstraction doesn’t mean miss config control, but I understand that may be outside from the project scope. Thanks for the response!

traxys commented 9 months ago

The problem is that we would need to choose what is "the" plugin to implement the diverse functionality, what do we do when there are multiple competing plugins ? We try to not be opinionated, so that can be quite tricky. Some plugins (let's say rust-tools.nvim) are a bit that already, but for other languages you may need a number of other plugins. What LSP should we choose for python? JS? If we need to expose them all it's a bit much maintainance burden, as we are not very knowldegable about most languages (I personally only know well the ecosystems of Rust & Nix)

zoedsoupe commented 9 months ago

That’s a really good point of view! Indeed this feature would demand a kinda complex implementation as it should handle different options for some packages. So for elixir for example, there’s the elixir-ls and the next-ls LSPs clients. So the desired API to declare this would be:

{
  programs.nixvim = {
    languages.elixir = {
      enable = true; # basic setup as tressiter grammar for example
      elixir-tools.enable = true; # specific plugin to handle other configs, as LSP
      linting.null-ls.enable = true; # enables Credo for static analysis, for example
      lsp = {
        enable = true;
        client = {
          name = “next-ls”; # can defaults to one or be a required option
          package = next-ls-derivation;
        };
      };
    };
  };
}

and for javascript (i don’t know much about the ecosystem too):

{
  programs.nixvim = {
    languages.javascript = {
      enable = true; # basic setup as tressiter grammar for example
      linting = {
        prettier.enable = true;
        # other linting options
      };
      lsp = {
        enable = true;
        client = {
          name = “javascript-typescript-langserver”;
          package = pkgs.javascript-lsp; # example name
        };
      };
    };
  };
}

Yeah, I agree it seems an extensible and complex feature but could be a valuable one! So if is decided to not go on, I’ll close this issue 😊

traxys commented 9 months ago

With this discussion I'm pretty convinced it's not the role of nixvim itself, but more of an opinionated wrapper around of nixvim for it to have a nice added value. From experience it's definitively though enough to follow the plugin options, it would be even harder to follow the ecosystem changes.

Though if a project builds upon nixvim to provide a more "batteries-included" approach we would include it gladly in the README!

zoedsoupe commented 9 months ago

Ok! Thanks for the discussion!