I'm trying to have python files format on save using black and neovim, with coc.

Coc config

I have the following coc config:

  "coc.preferences.useQuickfixForLocations": true,
  "coc.preferences.snippets.enable": true,

  // python config
  "python.venvFolders": [".virtualenvs"],
  "python.venvPath" : "~/",
  "python.linting.enabled": true,
  "python.linting.pylintEnabled": true,
  "python.jediEnabled": false,
  "python.formatting.provider": "black",
  "python.formatting.blackPath": "~/.virtualenvs/neovim/bin/black",
  "coc.preferences.formatOnSaveFiletypes": ["python"]

Venv packages

Within the venv above I have the following black version:

-> % which python

(neovim) x@y [14:31:38] [~/.virtualenvs]
-> % pip list | grep black
black           19.10b0

Other packages in this env are:

-> % pip list
Package         Version
--------------- ---------
appdirs         1.4.4
attrs           19.3.0
black           19.10b0
click           7.1.2
greenlet        0.4.16
isort           5.1.4
jedi            0.17.2
msgpack         1.0.0
neovim          0.3.1
numpy           1.19.1
pandas          1.0.5
parso           0.7.1
pathspec        0.8.0
pip             20.1.1
pynvim          0.4.1
python-dateutil 2.8.1
pytz            2020.1
regex           2020.7.14
setuptools      41.2.0
six             1.15.0
toml            0.10.1
typed-ast       1.4.1

Behaviour / errors

I see no errors, but I see no results. For example I would expect the following to work given that setup is functioning:

# from
# to (having saved file)

I don't get this though, nothing happens.

Something unusual that does happen is that my buffer for a python file is constantly in need of saving. By which I mean - I constantly have No write since last change warning when trying to do :q, which makes me think there's something funny going on, but I don't know where.


Here is the output of :checkhealth

Edit 2

Black seems to be working, for me, these are settings that I currently have.


   "python.formatting.provider": "black",
   "python.formatting.blackPath": "~/.virtualenvs/neovim/bin/black",
   "coc.preferences.formatOnSaveFiletypes": ["python"]

I also have nothing of the psf/black plugin anymore, that was (i think) causing some issues.

  • 1
    For what it's worth, I use ALE w/ black enabled for python and fix-on-save, and I never have issues with black.
    – D. Ben Knoble
    Commented Aug 1, 2020 at 23:46
  • I think coc config json files only take absolute path, so ~ should not work. Anyway, have you solved the issue?
    – Gordon Bai
    Commented Apr 25, 2021 at 18:38
  • i've not solved anything unfortunately
    – baxx
    Commented Apr 25, 2021 at 18:39
  • I need to correct my comment: I just confirmed ~ works (doesn't have to be absolute path). Also, after a long day of investigating this workflow for myself, I finally managed to understand the setup and it works for now. Are you interested in an answer here? If so I'll try to write up a setup process as answer.
    – Gordon Bai
    Commented Apr 25, 2021 at 21:58
  • @GordonBai if you have an answer that'd be great
    – baxx
    Commented Apr 26, 2021 at 11:12

3 Answers 3


This is a coc.nvim setup procedure that works for Neovim, which aims to:

  • Use coc-pyright as language server.

  • Provide static type checking from a Python virtualenv (e.g. I have created a venv called coc with pyenv, which resides in ~/.pyenv/versions, I'll use this as an example).

  • Format with black manually and automatically on save.

So here is my setup procedure:

  1. Configure venv in coc-settings.json:

      "python.venvPath": "/Users/gbai/.pyenv/versions"

    Here an absolute path is necessary for now, see this issue comment.

    Update: You could use ${env:HOME} (no space after :!) to replace ~:

      "python.venvPath": "${env:HOME}/.pyenv/versions"
  2. Choose a Python language server:

    Per coc.nvim's official doc section, I installed coc-pyright as language server by

    :CocInstall coc-pyright

    It has its own config file pyrightconfig.json per project, and should be placed at project root. I simply put this line in pyrightconfig.json:

      "venv": "coc"

    Of course for different project, the venv differs.

  3. Configure black

    Install black in the venv (coc in my config), and add these to coc-settings.json:

      "python.formatting.provider": "black",
      "python.formatting.blackPath": "~/.pyenv/versions/coc/bin/black"

    Interestingly, I can use relative path ~ here without problem.

  4. Formatting

    As per this issue comment:

    • Use "coc.preferences.formatOnType": true to enable format on type feature.

    • Use "coc.preferences.formatOnSaveFiletypes": ["python"] to include filetypes you want format on save.

    • Use :call CocAction('format') to format currrent document.

    • Use

      xmap <leader>f  <Plug>(coc-format-selected)
      nmap <leader>f  <Plug>(coc-format-selected)

      to format selected range.

    To inspect if formatting went well, as per this issue comment:

    coc-pyright v1.1.97 adds more formatting logs, you can get it by: :CocCommand workspace.showOutput - coc-pyright-formatting.

    through which you can tell if black is loaded and run correctly.

  5. Some more info

    Apart from using "coc.preferences.formatOnSaveFiletypes": ["python"] as mentioned above, also see this issue comment and another issue comment:

    The latest coc has added coc.preferences.willSaveHandlerTimeout, the default is 500ms, you can increase this time limitation.

    This is useful especially when you have very large files, which takes long to format.

Yes I have referenced a few issue comments where the actually instructions are. Maybe they should have a more detailed documentation :)

  • 1
    From the coc-pyright docs you can add an array to "python.formatting.blackArgs", e.g. : ["-l", "79"], to your coc-settings.json to specify arguments to black, as well. Commented Dec 14, 2021 at 2:06

I had the exact same issue. I solved it as below:

  1. Don't use black and isort from inside coc. Coc timeout issue mentioned by @Gorden Bai seems unresolved. My coc-settings.json:
    "python.sortImports.path": "/usr/bin/isort",
    "coc.preferences.willSaveHandlerTimeout": 1000,
    // this is required. Else coc looks for autopep8
    "python.formatting.provider": "black",
    "python.formatting.blackPath": "/usr/bin/black",
    // removed python from below to run black and isort independently
    "coc.preferences.formatOnSaveFiletypes": [
    "coc.source.around.firstMatch": false,
    "pyright.enable": true,
    "python.pythonPath": "/usr/bin/python",
    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "python.linting.flake8Path": "flake8",
    "python.linting.enabled": true 
  1. In init.vim:
call plug#begin('~/.vim/plugged')
Plug 'psf/black', { 'branch': 'main' }
Plug 'fisadev/vim-isort'
call plug#end()

" This triggers all formatting before coc linter is triggered
aug python
    autocmd BufWritePre *.py Isort
    autocmd BufWritePre *.py Black
aug END

P.S. I am not using virtual environment.

  • 1
    Welcome to the site Ashwin.
    – Dom
    Commented Dec 3, 2021 at 5:58

You don't really need coc to format on save.

See the official document: https://black.readthedocs.io/en/stable/integrations/editors.html#vim

After install black as a vim plugin, add this line in your .vimrc

autocmd BufWritePre *.py execute ':Black'

Or as @D.Ben Knoble pointed out

autocmd BufWritePre *.py Black
  • 1
    In fact you don’t need execute there
    – D. Ben Knoble
    Commented Jan 30, 2022 at 22:06
  • It errors if I remove execute
    – nos
    Commented Jan 31, 2022 at 15:49
  • 1
    autocmd BufWritePre *.py Black ?
    – D. Ben Knoble
    Commented Jan 31, 2022 at 16:03
  • I see, thanks. I was only copying from their tutorial
    – nos
    Commented Feb 1, 2022 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.