How to add the vim python code formatting black with nix

I am trying to add black to neovim, by adding it as a plugin. I am not able to find it in the nix packages, so I tried adding it on my own. This is my current neovim.nix:

{pkgs, ...}:
let
  black-vim = pkgs.vimUtils.buildVimPlugin {
    name = "black-vim";
    src = pkgs.fetchFromGitHub {
      owner = "psf";
      repo = "black";
      rev = "d852af71672ce22646017e4ca7a8878ca7bdfe39";
      sha256 = "c72fca000ed3e420230dc4370e4c118a5024191dd6f5eebf624881a9a5cc3a1a";
    };
  };
in 
  {
  programs.neovim = {
    enable = true;
    viAlias = true;
    vimAlias = true;

    plugins = with pkgs.vimPlugins; [
      black-vim
    ];
  };
}

I am able to run the :Black command in neovim, but I get the following error:

Please wait, one time setup for Black.
Creating a virtualenv in /home/john/.local/share/nvim/black...
(this path can be customized in .vimrc by setting g:black_virtualenv)
Encountered exception while creating virtualenv (see traceback below).
Removing /home/john/.local/share/nvim/black...
Error detected while processing function provider#python3#Call:
line   18:
Error invoking 'python_execute' on channel 5 (python3-script-host):
Traceback (most recent call last):
  File "<string>", line 103, in <module>
  File "<string>", line 79, in _initialize_black_env
  File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/venv/__init__.py", line 423, in create
    builder.create(env_dir)
  File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/venv/__init__.py", line 75, in create
    self._setup_pip(context)
  File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/venv/__init__.py", line 313, in _setup_pip
    subprocess.check_output(cmd, stderr=subprocess.STDOUT)
  File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/subprocess.py", line 420, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/nix/store/c1vb2z3c64i0sd92iz7fv0lb720qcvhb-python3-3.10.6/lib/python3.10/subprocess.py", line 524, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/home/john/.local/share/nvim/black/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
Error detected while processing function black#Black[10]..provider#python3#Call:
line   18:
Error invoking 'python_execute' on channel 5 (python3-script-host):
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'Black' is not defined

Do anyone know how I can add black to my neovim?

it told you that the pip command failed. Now it shouldn’t have to run pip as Black should be provided by nix and run through the g:python3_host_prog interpreter. You need to check how black.vim chooses the python to launch and if it detects an installed black python package, in which case you need to add it as a nix dependendy of the nix vim plugin

1 Like

Hi, I have both the following inside my home.nix

...
home.packages = with pkgs; [
  python310
  python310Packages.black
  python310Packages.virtualenv
];
...

I have also tried

...
home.packages = with pkgs; [
  (python310.withPackages(ps: with ps; [ black virtualenv ]))
];
...

what would I need to change in order to make it work? (sorry for being such a noob, but I really have tried for hours myself:))

looking at black/black.vim at d852af71672ce22646017e4ca7a8878ca7bdfe39 · psf/black · GitHub it seems like the plugin wants to create its own pyenv (rather than using a preexisting environment with black already installed), which means you wont gain much by installing the plugin via nix. I dont use any formatting plugin so I can’t really advise one. I would look at other plugins such as GitHub - lukas-reineke/lsp-format.nvim: A wrapper around Neovims native LSP formatting. or null-ls, if they dont run black in a more “nix”-compatible way.

1 Like

Does this mean that nixos and psf/black are incompatible?

Thank you very much for taking the time to help me btw!!

I just recently set this up with GitHub - neovim/nvim-lspconfig: Quickstart configs for Nvim LSP , GitHub - mattn/efm-langserver: General purpose Language Server and GitHub - lukas-reineke/lsp-format.nvim: A wrapper around Neovims native LSP formatting.

The latter seems optional but very comfy.

I’ll post the relevant configuration once I’m back on my PC. Nothing too wild but it’s quite a few different components

after a quick look psf/black doesn’t seem compatible with existing installs (on nixos or any other distribs). So either you install black as on any other distrib (with the virtualenv) or you patch black so that it picks up nix python package. @voydus has most likely a better solution.

1 Like

Ok so here’s my setup. This is using home-manager on arch linux.

{
  programs.neovim = {
    extraPackages = [
      pkgs.efm-langserver
      # I personally install black through project-specific flake.nix/shell.nix files,
      # but might as well add it here as well
      pkgs.black
    ];
    plugins = [
      pkgs.vimPlugins.lsp-format-nvim
      {
        plugin = pkgs.vimPlugins.nvim-lspconfig;
        config = ''
          lua <<EOF
            require("lsp-format").setup {}
            local on_attach = function(client)
                require("lsp-format").on_attach(client)
            end
            vim.cmd [[cabbrev wq execute "Format sync" <bar> wq]]

            lsp.efm.setup {
                init_options = {documentFormatting = true},
                settings = {
                    rootMarkers = { ".git/", "pyproject.toml" },
                    languages = {
                        python = { { formatCommand = "black -", formatStdin = true }, },
                    }
                },
                on_attach = on_attach,
            }
          EOF
        '';
      }
    ]
  }
}

My actual config is a lot bigger, so it’s possible I missed things, but afaict this should be enough. This is formatting on save, you might want to map vim.lsp.buf.format() if you prefer that.

Let me know if you have trouble with any of this or would like me to elaborate.

1 Like