Coc.nvim, nvim, stuff

I’m trying to use coc.nvim, and it works fine with the Rust LSP. However, I’m having trouble with the coc-python extension.

I’m using a global neovim from configuration.nix and nodejs, yarn, python with jedi and mypy all installed in a shell.nix which I activate via direnv.
I also put jedi as an extraPackage of neovim in configuration.nix, for good measure.

Result: I get linting errors allright, but the rest (jump to definition, …) doesn’t work.
Opening the coc log file, I see it is using a python interpreter that is not the one of the current shell, and I suppose also not the one from nvim, because it complains that jedi is not installed (but I can import jedi fine in the shell’s python.

I also tried to compile nvim with nodeJs support and removing it from shell.nix, but then nothing works anymore.

I’m a bit lost in who is using what, what the declared requirements of nvim are and what they affect, etc.

Can you enlighten me? :slight_smile:

Not 100% sure, not a nix user, yet. But I think you need to set up neovim to pick up the right python paths. Check :h g:python_host_prog & :h g:python3_host_prog

I might be able to help and I am actually interested in how you installed coc.nvim as it’s not packaged yet. Could you share this aspect of your config please ?

I’m currently handling my vim configuration outside of nix, actually (with the intent of more easy replication via a dotfiles repo to machines not running nix; assuming that’s a good reason for that).

Here is how I manage to get jedi into neovim, I am not sure it is the right way or not

(I need simple-websocket-server for vim-ghost)

# ~/.config/nixpkgs/overlays/neovim.nix

self: super:
with self.pkgs;
with self.python3Packages;

let
    # for ghost-text
    simple-websocket-server = buildPythonPackage rec {
      version = "git";
      pname = "simple-websocket-server";
      name = "${pname}-${version}";

      src = fetchFromGitHub {
        owner = "dpallot";
        repo = "simple-websocket-server";
        rev = "34e6def93502943d426fb8bb01c6901341dd4fe6";
        sha256 = "19rcpdx4vxg9is1cpyh9m9br5clyzrpb7gyfqsl0g3im04m098n5";
      };

      doCheck = false;
    };

    myPackages = p: with p; [
      simple-websocket-server
      python-slugify

      jedi
    ];
in
{
  neovim = super.neovim.override {
    extraPython3Packages = myPackages;
  };
}

If I understand correctly, I can also write the override in ~/.config/nixpkgs/config.nix instead of separate file for each package too.

1 Like

I packaged the most basic version of coc.nvim in unstable.
You can autoinstall extensions via
let g:coc_global_extensions = ['coc-extension1', 'coc-extension2', 'coc-extension3', 'coc-extension4'] though it’s not nix-declarative.
I haven’t tried the coc-python extension much as it seems to be WIP, require .Net code etc.

Instead I’ve kept my pyls config
I’ve updated the coc.nvim wiki this week with a full example Language servers · neoclide/coc.nvim Wiki · GitHub .
Btw thanks for pushing me to install coc.nvim, it’s really awesome especially with neovim 0.4-dev and the floating windows).

you might also be interested in vimPlugins.coc: init at 19.02.2019 · Pull Request #56091 · NixOS/nixpkgs · GitHub

Hey, just wanted to share a small caveat I noticed when configuring jedi for coc-python.

vim-ghost’s python is Neovim’s python executable - python3_host_prog. But, coc-python’s python executable is the first python which is found in $PATH. Therefor, you need to use direenv or a similar workaround to use coc-python.

I use the following as a base .envrc for my Python projects:

use nix -p python37Packages.{jedi,pylint}

To be further accurate, I feel I need to note that @wizzup’s example which adds jedi to the extraPythonPackages doesn’t help coc-python at all, according to my tests.

I use the following in my ~/.config/nixpkgs/config.nix:

    neovim = pkgs.neovim.override {
      extraPython3Packages = (ps: with ps; [
        simple-websocket-server
        python-slugify
      ]);
    };

So this is kind of a cleaner way IMO to do the same thing.

It is good to know that you have a successful setup. Thank you for your investigation.

I have virtually zero knowledge on Nix’s python system and python run-time things.

Now I know something :smile:

1 Like

Having a lot of trouble getting my python setup up and running as well. It would be awesome if you could share your config.

This is what works for me.

Vanilla neovim installed globally.

Per project, a default.nix containing:

let 
  pkgs = import <nixpkgs> {}; 
in
with pkgs;
let 
  mypython = pkgs.python3;
  ppkgs = mypython.pkgs;
  
  # whatever package you need that's not alredy packaged
  docx2txt = with ppkgs; callPackage ~/src/nixpkgs/docx2txt {};
  
  my-packages = python-packages: with python-packages; 
  [
    docx2txt
    langid  # whatever python packages you need

    # stuff for coc.nvim
    jedi
    mypy pylama
    black isort
  ];
  python-stuff = mypython.withPackages (my-packages);
in mkShell {
  buildInputs = [
    python-stuff

    # stuff for coc.nvim
    nodejs yarn 
  ];
  shellHook = ''
    rm -f env
    ln -s ${python-stuff}/bin env
  '';
}

Finally, in CocConfig:

{
  "coc.preferences.formatOnSaveFiletypes": ["rust", "python"],

  "rust-client.channel": "stable",
  "rust-client.disableRustup": true,
  "rust-client.logToFile": true,

  "python.autoComplete.showAdvancedMembers": false,
  "python.pythonPath": "./env/python",
  "python.formatting.provider": "black",
  "python.formatting.blackPath": "./env/black",
  "python.linting.mypyEnabled": true,
  "python.linting.mypyPath": "./env/mypy",
  "python.linting.pylintEnabled": false,
  "python.linting.pylamaEnabled": true,
  "python.linting.pylamaPath": "./env/pylama",
  "python.sortImports.path": "./env/isort"
}

I don’t know how much of this is actually needed, and certainly I could refactor default.nix and extract a shell.nix, but it’s good enough for now.

2 Likes

Do you think trying to keep global python-tools (black, jedi, etc) is a bad idea? I want to avoid repetition in all environments.

Black should be fine, but jedi will probably not see the packages that you install only in the environment of the project, since it’s a different Python environment.

Haven’t tried, though.

And repetition can be factored out in a derivation that you call in all environments - but I still haven’t done it ^^

1 Like

Anyone have idea how I have 2 output channels with the following test shell.nix ?

{ pkgs ? import <nixpkgs> {} }:
with pkgs;

let
  neovim = pkgs.neovim.override {
    configure = {
      packages.myVimPackage = with pkgs.vimPlugins; {
        start = [ coc-nvim ];
        };
      };
  };

in
stdenv.mkDerivation {
  name = "hello";
  buildInputs = [
    neovim
  ] ++ (with python3Packages; [
    python-language-server
  ]);
}

you’re right… I should think about my setups as any other code, that’s what nix is for after all. If I want to DRY, there are other ways to DRY than singletons/globals.

I just create the issue for duplicated message and got shutdown immediately. :zipper_mouth_face:

Anyone know other alternative completion plugin for neovim i should try?

The issue was solved!

Source of the problem is somehow there is coc-pyls extension installed in ~/.config/coc.

I don’t remember how , maybe by :CocInstall command (impurely)

Not sure about which one is the prefer way to install a coc plugins between pure vs impure.

Any idea?

coc-pyls is deprecated, isn’t it ? so far I don’t think anyone can or is using the microsoft server declaratively.
I’ve kinda managed to package mpls/make it accessible:

but I haven’t found a way to tell coc-python to use it.
I’ve had some code to build coc from source too but didn’t have the time to test it and the current coc installer is quite straightforward.

1 Like

why doesn’t the downloaded mpls just work? Missing dotnet dependencies? I wasn’t able to make it work in non-declarative install either

EDIT 1: I was getting enoent and just learned about ldd :grimacing:. Time for some debugging

EDIT 2:
not sure why libstdc++.so.6 isn’t found, is it because it’s in a non standard location on nix? I have the gcc package installed

ldd Microsoft.Python.LanguageServer
        linux-vdso.so.1 (0x00007fff7d318000)
        libpthread.so.0 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libpthread.so.0 (0x00007fa74ac12000)
        libdl.so.2 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libdl.so.2 (0x00007fa74ac0d000)
        libstdc++.so.6 => not found
        libm.so.6 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libm.so.6 (0x00007fa74aa77000)
        libgcc_s.so.1 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libgcc_s.so.1 (0x00007fa74a861000)
        libc.so.6 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib/libc.so.6 (0x00007fa74a6ab000)
        /lib64/ld-linux-x86-64.so.2 => /nix/store/wx1vk75bpdr65g6xwxbj4rw0pk04v5j3-glibc-2.27/lib64/ld-linux-x86-64.so.2 (0x00007fa74ac35000)

EDIT 3: Ok this makes it clearer Different methods to run a non-nixos executable on Nixos - Unix & Linux Stack Exchange

1 Like

Does anyone has a working example in the end?

1 Like