ayamir / nvimdots

A well configured and structured Neovim.
BSD 3-Clause "New" or "Revised" License
2.9k stars 452 forks source link

NixOS support #886

Closed misumisumi closed 1 year ago

misumisumi commented 1 year ago

Version confirmation

Following prerequisites

Neovim version

NVIM v0.9.1

Operating system/version

NixOS 23.11.20230718.684c17c (Tapir)

Terminal name/version

wezterm 20230712-072601-f4abf8fd

$TERM environment variable

xterm-256color

Branch info

main (Default/Latest)

Fetch Preferences

SSH (use_ssh = true)

How to reproduce the issue

If the python host prog is set on a system that does not support the Filesystem Hierarchy Standard (FHS), such as NixOS, dependencies related to python cannot be resolved. This is because NixOS uses a python environment on NixOS that is isolated from the system python, and this environment is set via command line arguments, which are overridden by nvimdots. A new configuration entry prevents nvimdots from overwriting it.

Expected behavior

:python3 import neovimで正常にimportされる。

Actual behavior

:python3 import neovimでエラーが発生する。

Additional information

No response

ayamir commented 1 year ago

I have used NixOS before. In fact, There are tons of changes need to be done to make the configuration work for NixOS. For example, all of lsp servers installed by Mason won't work on NixOS because its special file structure. This config is for the most GNU/Linux distribution which respects the LFS. IMO, it's better to create a NixOS branch to manage stuffs related to NixOS if we really need to support it.

misumisumi commented 1 year ago

You are right. The binary installed with mason.nvim is basically unusable on NixOS, you have to use the language server installed with nix! I once wrote a configuration for nvimdots for this project, but it requires significant changes, so I was thinking of doing my own support after separating the user settings as suggested in #885. I can make a proposal for a NixOS-compatible configuration in the near future.

fecet commented 1 year ago

I'm curious about nix, how does it work with conda?

misumisumi commented 1 year ago

You can use conda on NixOS, but packages that use libraries that depend on other languages, such as Cython, have a high probability of not working properly. This is because NixOS is not FHS compliant and cannot access libraries such as /usr/lib/. You need to build an environment with dependencies resolved using flake.nix or shell.nix. (like Dockerfile).

misumisumi commented 1 year ago

Also, if you are using the home-manager to manage neovim, the global python and the python used by neovim are managed separately. The fold is the content of nvim in NixOS. In NixOS, binaries are basically not executed directly, but from a shell script wrapper that resolves dependencies. (Each program has its own separate environment.) To access the language server, which is not installed globally and is written in python, you need to properly specify the python environment in which it is installed.

nvim on NixOS ```sh #! /nix/store/a7f7xfp9wyghf44yv6l6fv9dfw492hd3-bash-5.2-p15/bin/bash -e export NVIM_SYSTEM_RPLUGIN_MANIFEST='/nix/store/05xj82s93524lzrg30cww0sazx1wdfd6-neovim-0.9.1/rplugin.vim' export GEM_HOME='/nix/store/r5vapmr8hsj3c48nl77fdkxyph9m17hb-neovim-ruby-env/lib/ruby/gems/3.1.0' PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/r5vapmr8hsj3c48nl77fdkxyph9m17hb-neovim-ruby-env/bin'':'* ]]; then PATH=$PATH'/nix/store/r5vapmr8hsj3c48nl77fdkxyph9m17hb-neovim-ruby-env/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/r50qp4i6d4ry7x89aahwc22qz0y7fvzv-nodejs-18.16.1/bin'':'* ]]; then PATH=$PATH'/nix/store/r50qp4i6d4ry7x89aahwc22qz0y7fvzv-nodejs-18.16.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH LUA_PATH=${LUA_PATH:+';'$LUA_PATH';'} LUA_PATH=${LUA_PATH/';''/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/share/lua/5.1/?/init.lua'';'/';'} LUA_PATH='/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/share/lua/5.1/?/init.lua'$LUA_PATH LUA_PATH=${LUA_PATH#';'} LUA_PATH=${LUA_PATH%';'} export LUA_PATH LUA_PATH=${LUA_PATH:+';'$LUA_PATH';'} LUA_PATH=${LUA_PATH/';''/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/share/lua/5.1/?.lua'';'/';'} LUA_PATH='/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/share/lua/5.1/?.lua'$LUA_PATH LUA_PATH=${LUA_PATH#';'} LUA_PATH=${LUA_PATH%';'} export LUA_PATH LUA_CPATH=${LUA_CPATH:+';'$LUA_CPATH';'} LUA_CPATH=${LUA_CPATH/';''/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/lib/lua/5.1/?.so'';'/';'} LUA_CPATH='/nix/store/x8j4191ax47lq08d3620za8j4rpxfzdj-luajit-2.1.0-2022-10-04-env/lib/lua/5.1/?.so'$LUA_CPATH LUA_CPATH=${LUA_CPATH#';'} LUA_CPATH=${LUA_CPATH%';'} export LUA_CPATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/hw2xmrqirmrq4f3vl7nbf53ivif8gny7-cargo-1.70.0/bin'':'* ]]; then PATH=$PATH'/nix/store/hw2xmrqirmrq4f3vl7nbf53ivif8gny7-cargo-1.70.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/1b4vykls7dlbyhw2jygcz7wgf86i7x3n-deno-1.35.1/bin'':'* ]]; then PATH=$PATH'/nix/store/1b4vykls7dlbyhw2jygcz7wgf86i7x3n-deno-1.35.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/x7n44lfys59k5ajj9w1fkxw5391cnn5v-gcc-wrapper-12.3.0/bin'':'* ]]; then PATH=$PATH'/nix/store/x7n44lfys59k5ajj9w1fkxw5391cnn5v-gcc-wrapper-12.3.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/3l1hdz7xqyh1qhq9yn6cm8cfl3n1gyd3-gnumake-4.4.1/bin'':'* ]]; then PATH=$PATH'/nix/store/3l1hdz7xqyh1qhq9yn6cm8cfl3n1gyd3-gnumake-4.4.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/nvydgjdaff1i887x2fk8kygcrbxyfyiy-go-1.20.5/bin'':'* ]]; then PATH=$PATH'/nix/store/nvydgjdaff1i887x2fk8kygcrbxyfyiy-go-1.20.5/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/vy6qf5ny58a2pr21q1hx4p9hgians0sc-ninja-1.11.1/bin'':'* ]]; then PATH=$PATH'/nix/store/vy6qf5ny58a2pr21q1hx4p9hgians0sc-ninja-1.11.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/vfqcpzf6a6dy1iy3f51gwfny0ks7rgld-patchelf-0.15.0/bin'':'* ]]; then PATH=$PATH'/nix/store/vfqcpzf6a6dy1iy3f51gwfny0ks7rgld-patchelf-0.15.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/d9hc3hfmxrpfrh8qmckqnbdwkxpfand8-sqlite-3.42.0-bin/bin'':'* ]]; then PATH=$PATH'/nix/store/d9hc3hfmxrpfrh8qmckqnbdwkxpfand8-sqlite-3.42.0-bin/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/k75gz90y97nw6hv4n6fprf9dlv25k3yv-yarn-1.22.19/bin'':'* ]]; then PATH=$PATH'/nix/store/k75gz90y97nw6hv4n6fprf9dlv25k3yv-yarn-1.22.19/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/x4a5mk7z25h5mcm2895izm6fqqr77wm6-xclip-0.13/bin'':'* ]]; then PATH=$PATH'/nix/store/x4a5mk7z25h5mcm2895izm6fqqr77wm6-xclip-0.13/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/l74qmkwqbpcickrh51nf60j9d5cf3h6c-ripgrep-13.0.0/bin'':'* ]]; then PATH=$PATH'/nix/store/l74qmkwqbpcickrh51nf60j9d5cf3h6c-ripgrep-13.0.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/hcn4y9ymmc10yan23xz7llajkmvqjcng-neovim-remote-2.5.1/bin'':'* ]]; then PATH=$PATH'/nix/store/hcn4y9ymmc10yan23xz7llajkmvqjcng-neovim-remote-2.5.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/hl0xb3ljxiaxgm8xgn89x2lm4dmki3j6-bash-language-server-5.0.0/bin'':'* ]]; then PATH=$PATH'/nix/store/hl0xb3ljxiaxgm8xgn89x2lm4dmki3j6-bash-language-server-5.0.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/fw8p64rw0jixi9yaqwcdjqcbb9x1511r-clang-tools-14.0.6/bin'':'* ]]; then PATH=$PATH'/nix/store/fw8p64rw0jixi9yaqwcdjqcbb9x1511r-clang-tools-14.0.6/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/jv0pwsrcq9p7r2r8af0bljxi3icpi4nk-csharp-ls-0.8.0/bin'':'* ]]; then PATH=$PATH'/nix/store/jv0pwsrcq9p7r2r8af0bljxi3icpi4nk-csharp-ls-0.8.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/5h1zq4qf112b7z2yhmw77bazj9xcq740-efm-langserver-0.0.44/bin'':'* ]]; then PATH=$PATH'/nix/store/5h1zq4qf112b7z2yhmw77bazj9xcq740-efm-langserver-0.0.44/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/17sfw9qhbscynh9h1yf7jswxnn13ajf5-eslint-8.45.0/bin'':'* ]]; then PATH=$PATH'/nix/store/17sfw9qhbscynh9h1yf7jswxnn13ajf5-eslint-8.45.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/cpya7699rjkr1wznqwcdwds5gzqx6q8p-gopls-0.12.4/bin'':'* ]]; then PATH=$PATH'/nix/store/cpya7699rjkr1wznqwcdwds5gzqx6q8p-gopls-0.12.4/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/bs0y5fk4ly0ghj6xcpb9rs0acrm6qzkd-haskell-language-server-2.0.0.0/bin'':'* ]]; then PATH=$PATH'/nix/store/bs0y5fk4ly0ghj6xcpb9rs0acrm6qzkd-haskell-language-server-2.0.0.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/1nv9gvss7bbmm9ikyr2wsqw9ji4yqmrn-vscode-html-languageserver-bin-1.4.0/bin'':'* ]]; then PATH=$PATH'/nix/store/1nv9gvss7bbmm9ikyr2wsqw9ji4yqmrn-vscode-html-languageserver-bin-1.4.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/9daxxhi06gbib93k98yim9x7m0pidl1p-vscode-json-languageserver-1.3.4/bin'':'* ]]; then PATH=$PATH'/nix/store/9daxxhi06gbib93k98yim9x7m0pidl1p-vscode-json-languageserver-1.3.4/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/1xw35gw67b20qzn2k6m18y7xswl04kxl-lua-language-server-3.6.23/bin'':'* ]]; then PATH=$PATH'/nix/store/1xw35gw67b20qzn2k6m18y7xswl04kxl-lua-language-server-3.6.23/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/0zx7rwda8c7xncq4wnlbpf28pfja44na-marksman-2023-03-04/bin'':'* ]]; then PATH=$PATH'/nix/store/0zx7rwda8c7xncq4wnlbpf28pfja44na-marksman-2023-03-04/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/pl73ayc481hi2plkfw0cpm4csvjmjhbf-nil-2023-05-09/bin'':'* ]]; then PATH=$PATH'/nix/store/pl73ayc481hi2plkfw0cpm4csvjmjhbf-nil-2023-05-09/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/dg31145d9ssk7kvc8c1yf3iv71l12sbs-pyright-1.1.317/bin'':'* ]]; then PATH=$PATH'/nix/store/dg31145d9ssk7kvc8c1yf3iv71l12sbs-pyright-1.1.317/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/irmk9r7cf3pb7xwq53isv4cwvcldi1z6-taplo-0.8.1/bin'':'* ]]; then PATH=$PATH'/nix/store/irmk9r7cf3pb7xwq53isv4cwvcldi1z6-taplo-0.8.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/wk865sdshhv1c70ijxpi3zyrvx8hqaqa-terraform-ls-0.31.3/bin'':'* ]]; then PATH=$PATH'/nix/store/wk865sdshhv1c70ijxpi3zyrvx8hqaqa-terraform-ls-0.31.3/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/046q858668makmbr4mxqig036ckv9ss3-texlab-5.7.0/bin'':'* ]]; then PATH=$PATH'/nix/store/046q858668makmbr4mxqig036ckv9ss3-texlab-5.7.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != *':''/nix/store/9761naw3l6pzwxx5sxkh9lfyz7mgvrwg-alejandra-3.0.0/bin'':'* ]]; then PATH=$PATH'/nix/store/9761naw3l6pzwxx5sxkh9lfyz7mgvrwg-alejandra-3.0.0/bin' fi

PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/yhg7zdhm68npjf7mwfzhk06m4c7j78x3-python3.10-black-23.3.0/bin'':' ]]; then PATH=$PATH'/nix/store/yhg7zdhm68npjf7mwfzhk06m4c7j78x3-python3.10-black-23.3.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/fw8p64rw0jixi9yaqwcdjqcbb9x1511r-clang-tools-14.0.6/bin'':' ]]; then PATH=$PATH'/nix/store/fw8p64rw0jixi9yaqwcdjqcbb9x1511r-clang-tools-14.0.6/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/4xyxhdvsrlnhix4dbi7c8mfddxxj6zgz-prettier-3.0.0/bin'':' ]]; then PATH=$PATH'/nix/store/4xyxhdvsrlnhix4dbi7c8mfddxxj6zgz-prettier-3.0.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/5gjj5wpcaa6zh1sh3163b2g1f6nryds9-rustfmt-1.70.0/bin'':' ]]; then PATH=$PATH'/nix/store/5gjj5wpcaa6zh1sh3163b2g1f6nryds9-rustfmt-1.70.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/682jxw3nnp08jprsi1aldlzrvrj6rpnj-shfmt-3.7.0/bin'':' ]]; then PATH=$PATH'/nix/store/682jxw3nnp08jprsi1aldlzrvrj6rpnj-shfmt-3.7.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/lwljm6b3r4l26bx8s99jvx712ymvxiij-stylua-0.18.1/bin'':' ]]; then PATH=$PATH'/nix/store/lwljm6b3r4l26bx8s99jvx712ymvxiij-stylua-0.18.1/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/hwmr1i0sh9achlgnlq8yxg7smhm0w08h-terraform-1.5.3/bin'':' ]]; then PATH=$PATH'/nix/store/hwmr1i0sh9achlgnlq8yxg7smhm0w08h-terraform-1.5.3/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/5z808vcd8481c3ya120yr941qnidqx23-python3.10-flake8-6.0.0/bin'':' ]]; then PATH=$PATH'/nix/store/5z808vcd8481c3ya120yr941qnidqx23-python3.10-flake8-6.0.0/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/v8rsqa5qvijjq4q7ivnjw7sjl9v02xcc-vim-vint-0.3.21/bin'':' ]]; then PATH=$PATH'/nix/store/v8rsqa5qvijjq4q7ivnjw7sjl9v02xcc-vim-vint-0.3.21/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/22saljw2b8fnl3aw0mh7j0jjgmc2lkkg-shellcheck-0.9.0-bin/bin'':' ]]; then PATH=$PATH'/nix/store/22saljw2b8fnl3aw0mh7j0jjgmc2lkkg-shellcheck-0.9.0-bin/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH PATH=${PATH:+':'$PATH':'} if [[ $PATH != ':''/nix/store/k4ciwh7qxba15g3cm3vnvkcy4kfbpwhq-statix-0.5.6/bin'':' ]]; then PATH=$PATH'/nix/store/k4ciwh7qxba15g3cm3vnvkcy4kfbpwhq-statix-0.5.6/bin' fi PATH=${PATH#':'} PATH=${PATH%':'} export PATH exec -a "$0" "/nix/store/mmp203bf0m9cz39di4pj1xq456ffjwbf-neovim-unwrapped-0.9.1/bin/nvim" --cmd "lua vim.g.node_host_prog='/nix/store/05xj82s93524lzrg30cww0sazx1wdfd6-neovim-0.9.1/bin/nvim-node';vim.g.loaded_perl_provider=0;vim.g.loaded_python_provider=0;vim.g.python3_host_prog='/nix/store/05xj82s93524lzrg30cww0sazx1wdfd6-neovim-0.9.1/bin/nvim-python3';vim.g.ruby_host_prog='/nix/store/05xj82s93524lzrg30cww0sazx1wdfd6-neovim-0.9.1/bin/nvim-ruby'" "$@"

</details>

<details>
<summary>home-manager config</summary>

```nix
#  neovim conf
#  I use conf sourcing ./nvim but you can manager from home manager.
{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.programs.neovim.useMyDots;
  json = importJSON ../../lsp/pkgs.json;
  json2list = x: attrsets.mapAttrsToList (name: value: value) x;
  sp = x: splitString "." x;
  list2pkg = pkgs: list:
    with builtins;
      map (x:
        if length (sp x) > 1
        then pkgs."${head (sp x)}"."${head (drop 1 (sp x))}"
        else pkgs."${x}")
      list;
in {
  options = {
    programs.neovim.useMyDots = {
      enable = mkEnableOption ''
        My nvim config
      '';
    };
  };
  config = mkIf cfg.enable {
    xdg = {
      configFile = {
        "nvim/lua".source = ../../lua; # windowsとconfigを共有するため.config/nvimで管理する
        "nvim/init.lua".source = ../../init.lua;
        "nvim/lsp".source = ../../lsp;
        "latexmk".source = ../../latexmk;
      };
    };
    home.sessionVariables = {
      SQLITE_CLIB_PATH = "${pkgs.sqlite.out}/lib/libsqlite3.so";
    };

    programs.neovim = {
      enable = true; # Replace from vi&vim to neovim
      viAlias = true;
      vimAlias = true;
      vimdiffAlias = true;

      withNodeJs = true;
      withPython3 = true;
      withRuby = true;

      extraPackages = with pkgs;
        [
          cargo
          deno
          gcc
          gnumake
          go
          ninja
          patchelf
          sqlite
          yarn
          xclip

          ripgrep

          # LSP
          neovim-remote
        ]
        ++ list2pkg pkgs (json2list json.lsp)
        ++ list2pkg pkgs (json2list json.null-ls.formatting)
        ++ list2pkg pkgs (json2list json.null-ls.diagnostics)
        ++ list2pkg pkgs (json2list json.null-ls.code_actions);

      extraPython3Packages = ps:
        with ps; [
          isort
          docformatter
          doq
          pynvim
        ];
    };
  };
}

fecet commented 1 year ago

Also I guess https://github.com/ayamir/nvimdots/blob/b44d0152207cd0d9e03e79294b1e28771edea209/lua/core/options.lua#L111-L114 are not necessary as conda always set it's path at very first so python should refer to it correctly

CharlesChiuGit commented 1 year ago

Also I guess

https://github.com/ayamir/nvimdots/blob/b44d0152207cd0d9e03e79294b1e28771edea209/lua/core/options.lua#L111-L114

are not necessary as conda always set it's path at very first so python should refer to it correctly

cant really test this since i dont use conda nowadays. I use asdf-vm now.

fecet commented 1 year ago

just check https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#activating-an-environment

Conda prepends the path name myenv onto your system command.

misumisumi commented 1 year ago

As mentioned in #887, I sent an issue and pull req for NixOS support. Certainly there is now a wide variety of python development environments and many things could be considered for changing the python_host_prgo option. Therefore, I want to change the title of the Issue to "About support for NixOS" since it is likely to spread to the whole python development environment. However, I have my doubts that NixOS support should be tackled in your project because of the small number of users, the unique handling of LSP and nvim-treesitter, and the increased effort to keep up with changes to NixOS or home-manager upstream. If you are interested in discussing NixOS support, I have implemented initial support at misumisumi/nvimdots/nixos-support. What do you think?

Jint-lzxy commented 1 year ago

@misumisumi If I understand correctly does supporting NixOS imply that we mainly need to avoid these two:

The former is not that difficult to tackle - as after #738, all executables except for those Python-related stuffs will be handled by the operating system instead. This assigns the responsibility for correctly specifying Neovim itself and its potential providers (which :Mason cannot handle) to users.

For the latter, can NixOS provide a solution from "the other side" of the issue (i.e., let Mason automate this process)? From misumisumi/nvimdots/nixos-support, looks like the problem is the executable itself works, but it can't correctly parse (or locate) its dependencies (correct me if i'm wrong). Does NixOS provide any tools that can modify an executable's ELF data (like install_name_tool on macOS for Mach-O)? If this is possible, simply changing the executable's dynamic linker that it relies on can reliably resolve the problem (unless its load path is an absolute path, but a quick scan of those commonly used packages didn't reveal this) FWIW if this is supported, it is also possible for Neovim on NixOS to receive long-term support in this repo.

misumisumi commented 1 year ago

The issues to be avoided are as you point out. The other is that some languages have errors when compiling nvim-treesitter due to dependency issues.

Absolute paths to executables specified wrt FHS;

Simply specify the command to be executed as you would normally use in a distibution. In other words, as long as the path is passed in which <cmd>, you are good to go.

Executables using FHS-conforming dynamic linkers & RPATH specifications.

It is possible to patch ELF using hooks during mason installation. However, it is quite tedious to patch every NixOS (linker) update and enumerate the necessary libraries. Dependencies are resolved for individual packages by the nix package manager. Therefore, I prefer to use nix package manager for NixOS.

From misumisumi/nvimdots/nixos-support, looks like the problem is the executable itself works, but it can't correctly parse (or locate) its dependencies (correct me if i'm wrong).

In my implementation, the packages used by LSP, fomatter and code_action etc (using from null-ls) and DAP are installed by nix package manager without using mason.nvim. I have not deactivated mason.nvim because I want to use the mason-nvim-dap.nvim resource. I use nixos/mappings.json for control because the names of nix and, for example, nvim-lspconfig are different. I have not yet checked everything about nvim-treesitter.

In other words, as long as the path is passed in which , you are good to go.

When neovim is managed by home-manager, packages such as language server are not installed globally, but a separate environment is created by nix that contains them. This means that they can only be accessed from a shell invoked with :terminal. You do not need to be aware of this when using it, but you should keep in mind that it is not accessible from another terminal when debugging.

CharlesChiuGit commented 1 year ago

seems like a lot of work :open_mouth:

Jint-lzxy commented 1 year ago

Simply specify the command to be executed as you would normally use in a distibution. In other words, as long as the path is passed in which <cmd>, you are good to go.

Thanks for the info. In this case, #738 will surely do its job. We only need to make some changes to Python-related stuffs then. Possibly also via vim.fn.exepath.

It is possible to patch ELF using hooks during mason installation. However, it is quite tedious to patch every NixOS (linker) update and enumerate the necessary libraries. Dependencies are resolved for individual packages by the nix package manager. Therefore, I prefer to use nix package manager for NixOS.

AFAIK Mason also has an event (although it seems private), which can be used to detect updates to dynamic linkers. The thing is, is it possible to have a centralized storage/reference location(s) (of symlinks) to activated packages (or "user-profile" in short), where u or ur package manager help u manage these symlinks? e.g.:

~/.my_profile/lib => ~/.my_profile/<hash>/lib:
lrwxr-xr-x jint admin  48 B  Sat Jun 17 12:22:08 2023 libboost_json.dylib => ../Cellar/boost/1.82.0_1/lib/libboost_json.dylib

This way, each session only needs to specify its dynamic linker and everything should work. e.g.:

LD_LIBRARY_PATH="/path/to/your/profile/lib:/path/to/your/system/lib:$LD_LIBRARY_PATH"
<mod-elf> --libdyld /path/to/your/profile/lib/ld.so <exec-to-be-patched> # Modified via Mason
##### Or a persistent solution #####
<mod-elf> --prepend-rpath "$LD_LIBRARY_PATH" <exec-to-be-patched> # Modified via Mason

When neovim is managed by home-manager, packages such as language server are not installed globally, but a separate environment is created by nix that contains them. This means that they can only be accessed from a shell invoked with :terminal. You do not need to be aware of this when using it, but you should keep in mind that it is not accessible from another terminal when debugging.

Can this issue be alleviated by using the above method? Cause all packages will instead use ~/.local/share/nvim/mason/packages.

misumisumi commented 1 year ago

The thing is, is it possible to have a centralized storage/reference location(s) (of symlinks) to activated packages (or "user-profile" in short), where u or ur package manager help u manage these symlinks?

I think it is possible to create a custom package that bundles the required shared libraries it depends on, install it in the environment, and then set up the RPATH. Indeed, it may be a bit challenging to determine which packages depend on which libraries. In any case, I'll give it a try and create it once.

However, it seems like it has been abandoned, as discussed in mason.nvim#428.

Jint-lzxy commented 1 year ago

I just randomly browsed through the NixOS reference manual and bumped into package-management/profiles, will this help?

Example setup (modified based on https://github.com/williamboman/mason.nvim/issues/428#issuecomment-1258919407):

patchelf --set-interpreter /home/USER/.nix-profile/lib/ld-linux-x86-64.so.2 ${mason_registry_entry}
export LD_LIBRARY_PATH="/home/USER/.nix-profile/lib:/nix/var/nix/profiles/system/sw/lib/:/lib64/:/usr/lib64/:$LD_LIBRARY_PATH"
### persistent patch ###
patchelf --set-rpath "$LD_LIBRARY_PATH" ${mason_registry_entry}

I think it is possible to create a custom package that bundles the required shared libraries it depends on

FYI, this is a non-exhaustive list of dependencies generated via otool -L / grepping the mason registry:

[Required: Nvim]
libluv.1.dylib
libtermkey.1.dylib
libvterm.0.dylib
libmsgpack-c.2.dylib
libtree-sitter.0.dylib
libunibilium.4.dylib
libintl.8.dylib
libluajit-5.1.2.dylib
libutil.dylib
libuv.1.dylib

[Required: Mason-registries]
libiconv.2.dylib
libz.1.dylib
libresolv.9.dylib
libc.6.dylib
libstdc++.6.dylib (GCC) [OR] libc++.1.dylib (LLVM)
libobjc.A.dylib (if possible via GNUStep)

[Required: Mason]
unzip
wget
curl
gzip
tar
bash [OR] sh
ruby
go
cargo
gem (RubyGem)
luarocks
node
java
npm
python [OR] python3
javac
pip
julia
php
composer

However, it seems like it has been abandoned, as discussed in https://github.com/williamboman/mason.nvim/issues/428#issuecomment-1380128813.

I think what williamboman means is this will not receive upstream support, but those hooks are still available, which implies configuration on a per-repo basis is still feasible.

misumisumi commented 1 year ago

Thank you for your research!

FYI, this is a non-exhaustive list of dependencies generated via otool -L / grepping the mason registry:

I've been struggling with enumerating required dependencies and this is very helpful! I'll get started right away.

Mason also has an event (although it seems private), which can be used to detect updates to dynamic linkers.

Can you think of a way to detect dynamic linker updates from mason?

I just randomly browsed through the NixOS reference manual and bumped into package-management/profiles, will this help?

Unfortunately this is the path hierarchy when using the nix package manager alone. The top level hierarchy is quite different when called from NixOS or from home-manager. (Top level is NixOS is /run/current-system/sw/{bin, lib, ...}, home-manager is `/etc/profiles/per-user//{bin,lib,...}) However, since only /nix/store is immutable, I would like to adopt a method of saving and referencing the path of the created package in an environment variable. As far as I know, the nix package manager is rarely used alone, and is often used via some kind of tool. So I will focus on what is available from home-manager.

Jint-lzxy commented 1 year ago

Can you think of a way to detect dynamic linker updates from mason?

Mason has a private API that was originally (and intended to be) used to check for updates for its registries (by comparing version numbers), but this can also be used to check other executables.

misumisumi commented 1 year ago

Can you tell me the API for that?

Jint-lzxy commented 1 year ago

Can you tell me the API for that?

I'm afraid I can't tell you right away (I forget its name). I scanned the source code of mason.nvim a few weeks ago, attempting to debug a weird Mach error, and found that function. But it has been some time now and I am not sure where it resides. I will check this later and let you know when I find that.

Jint-lzxy commented 1 year ago

@misumisumi It's check_thunk(opts) which can be integrated with Mason

misumisumi commented 1 year ago

Think you! I checked.


I want to discuss a bit about installing packages. For all packages handled by mason.nvim, dependencies were resolved so that packages that needed to be built could be built. However, currently the following packages cannot be built due to upstream problems in the package or nixpkgs or it takes time to identify the cause.

I also have concerns about ELF patches to binaries. Refer to check_thunk(opts) to determine whether the installed binary is executable. However, the problem is that the symlinks that exist in nvim/mason/bin do not necessarily link to the executable binary. For example, lua-language-server is linked to nvim/mason/packages/lua-language-server/lua-language-server, but this is a shell script and the actual binary is nvim/mason/packages/ Located in lua-language-server/libexec/bin/lua-language-server. This means that we unable to trace with readfile -f and need to facilitate path mapping for certain packages. mason.nvim has a function that returns the install location, but you should be able to resolve the path to the executable binary on your own. In other words, there is a high possibility that countless descriptions such as the following will be necessary.

if pkg.name == "lua-language-server" then
        bin_abs_path = pkg:get_install_path() .. "/libexec/bin/lua-language-server"
        os.execute(("patchelf --set-interpreter %s %s"):format(interpreter, bin_abs_path))
misumisumi commented 1 year ago

Here a comparison using mason.nvim and nixpkgs

Using mason.nvim

Using nixpkgs

misumisumi commented 1 year ago

In any case, proceed with the implementation of the setup process using mason.nvim.

Jint-lzxy commented 1 year ago

I also have concerns about ELF patches to binaries. Refer to check_thunk(opts) to determine whether the installed binary is executable.

I'm prone to using this to check the version of the dynamic linker, and perform updates whenever it's necessary. mason-org/mason-registry provides rich information about each package. We can (and should) use its API to correctly handle patchelf related issues. I'm pretty sure this will work b/c I'm also using this to address dependency issues on my system (via install_name_tool -add_rpath ${mason_exec}).

ELF patch processing becomes complicated?

If we use mason-registry, only one post-install hook needs to be registered. Not that complicated I think?

IMO for long-term benefits and to reduce maintenance pressure, we should stick with Mason. b/c external package managing adds a lot of uncertainty (and a layer of indirection) to the entire config, whereas Mason integrates well with Neovim, and as long as any package is registered there, it can be used within Neovim. For users who want to minimize dependencies, they can comment out unnecessary ones upon installation to keep their configuration as simple as possible, while also enjoying automated package installation inside Neovim. But for incompatible executables, if really necessary, users can install them by other means and manually setup that as well. E.g.: https://github.com/ayamir/nvimdots/blob/6de8afe0fc4a6e53a9d64a013327d5482b6dbe99/lua/modules/configs/completion/lsp.lua#L143-L148

Another benefit is, to uninstall Neovim, one only need to remove the directory pointed to by stdpath (and Neovim itself). No additional cleaning needs to be performed.

Jint-lzxy commented 1 year ago

java-language-server: Maybe no java module ?

This is a tricky one to install, jdtls would suffice though.

misumisumi commented 1 year ago

But for incompatible executables, if really necessary, users can install them by other means and manually setup that as well. E.g.:

I was adamant about ending with mason.nvim. Certainly, if you want to use nixpkgs-derived commands, that method is sufficient.

misumisumi commented 1 year ago

I came across nix-ld while researching how to run executable binaries on NixOS. This automatically resolves LD and LD_LIBRARY which are resolved by patchelf. By specifying the dependent packages using this, the executable binary becomes executable. I confirmed that marksman and lua-language-server installed by mason.nvim actually work. This allows you to tweak your neovim configuration very little. The fix on the neovim side is to set the sqlite_clib_path appropriately, just like on windows. This used a similar solution as conda_prefix. In other words, a way to try to read the path to sqlite mentioned in the environment edit from the neovim side.

The problem was creating NixOSModule for home-manager. It is not desirable to keep LD_LIBRARY_PATH, 'LIBRARY_PATH`, etc. as environment variables for the entire session because the development environment will be polluted.

the solution is to create nvim alias that includes various environment variables so that it is not exposed to anything other than neovim. I considered extending pkgs.wrapNeovimUnstable to wrap environment variables, but I also needed to modify the implementation of home-manager, so I used alias. Environment variable creation were solved by mimicking nix-ld's NixOSModule. Creating an option of NixOSModule allows users to easily add build dependencies This specification is complete as NixOSModule for home-manager, so it works even if you use home-manager on another distribution. However, environment variables such as LIBRARY_PATH may cause build problems on non-NixOS environments. Non-NixOS distributions are generally considered FHS compliant and will build properly without environment variables. Therefore, setting environment variables is optional. In addition, each language support is also supported by creating options for NixOSModule.

dotnet created NixOSModule separately. This is inspired by programs.java in home-manager to make it easier for users to change the runtime and configure DOTNET. I think the dotnet module should be managed upstream, so I'd like to propose it.

wmmiiii commented 1 year ago

how to configurate the jdtls to use java module?

CharlesChiuGit commented 1 year ago

check wiki first

Parsifa1 commented 1 month ago

Maybe nix users can try configuring nix-ld, on my nixos machine this works very smoothly

CharlesChiuGit commented 1 month ago

Maybe nix users can try configuring nix-ld, on my nixos machine this works very smoothly

https://github.com/Mic92/nix-ld?tab=readme-ov-file#does-this-work-on-non-nixos-system

Does this work on non-NixOS system? No. Normal Linux distributions will have their own link-loader. Replacing those with nix-ld will break the system.

if ppl use nix/home-manager on other *nix system, nix-ld will break the system.

Parsifa1 commented 1 month ago

Maybe nix users can try configuring nix-ld, on my nixos machine this works very smoothly

Mic92/nix-ld#does-this-work-on-non-nixos-system

Does this work on non-NixOS system? No. Normal Linux distributions will have their own link-loader. Replacing those with nix-ld will break the system.

if ppl use nix/home-manager on other *nix system, nix-ld will break the system.

Oh, I forget that you can use nix on other distro, sorry(