I'm using the psf/black plugin, I install and load it with vimplug: Plug 'psf/black' and I use it with <leader>f: autocmd FileType python nmap <leader>f :Black<CR>

I use and prefer 2 space indentation with JavaScript (Prettier), Python and most of the other programming languages I use, that's why I have the following in my init.vim (nvim config):

    set ignorecase
    set smartcase
    filetype plugin indent on
    " show existing tab with 2 spaces width
    " delete 2 spaces on backspace
    set softtabstop=2
    " when indenting with '>', use 2 spaces width
    set shiftwidth=2
    " On pressing tab, insert 2 spaces
    set expandtab

I can't get the Black plugin to indent 2 spaces instead of 4, I have tried making an .editorconfig file with indent_size = 2 and it didn't work.


It looks like the Black Python code formatter intentionally does not allow you to configure whether to use 2 or 4 spaces, which makes me wonder why, I can't imagine this change requiring anything other than a minimal change to the code, the lack of the explanation to why they are not and won't support it makes me think that it is not a matter of religiously sticking to a subset of PEP8 (which recommended 4 spaces, in 2001) but a matter of enforcing their personal preference on the world.

It looks like the forks that implemented this feature are abandoned or not as maintained as the upstream repository.

So I'd recommend to keep using this plugin and use a simple command that replaces each 4 spaces at the beginning of each line with 2. which its implementation turned out to be suspiciously simple:

import pynvim
import re

class Iindent(object):
  """ Iindent plugin: Black can't stop me from using 2 spaces """
  def __init__(self, nvim):
    self.nvim = nvim
    self.pattern = re.compile(r"^(\s\s\s\s)+")

  @pynvim.command("Iindent", nargs="*", range="")
  def iindent(self, args, range):
    buffer = self.nvim.current.buffer
    new_buffer = []
    for line in buffer:
      x = self.pattern.search(line)
      if x:
        _, end = x.span()
        line = re.sub(self.pattern, " " * int(end / 2), line)
      new_buffer += [line]
    buffer[:] = new_buffer

it uses and depends on pynvim, install it with pip pip install --user pynvim or better yet install it with your distro's package manager which upgrades it with vim automatically for you, I use Arch so I installed it with Sudo pacman -S python-pynvim

make a directory for this new plugin in the plugged directory which is in your vim config directory: mkdir -p ~/.vim/plugged/iindent/rplugin/python3 make a new python file in it: touch ~/.vim/plugged/iindent/rplugin/python3/iindent.py and add to it the code above, then install with vimplug/your-plugin-manager by adding Plug '~/.vim/plugged/iindent' to your vim config and running :UpdateRemotePlugins

then change your <leader>f keybinding command to run this command after Black: autocmd FileType python nmap <leader>f :Black<CR> :Iindent<CR>

a down-side to this approach is that it adds an extra indentation change to history in-addition-to/after the formatter change, however the upside is that you keep using the maintained plugin and formatter.

  • 4
    "enforcing their personal preference on the world" The problem with allowing customizations or too many configurations on a tool that's expected to provide standard style formatting can be summarized by this: xkcd.com/927 "Now there are 15 styles." When working in a team or in open source projects, there are huge benefits to have everyone adhere to the same rules. All the tools will be able to enforce them. Automatic formatting means it will be handled automatically, so you don't need to worry about it. – filbranden Mar 12 '20 at 15:56
  • 1
    @filbranden I totally get that, the team as whole decide on their style and configure their linter and formatters accordingly with config files that are tracked with source control. that's why Black's config file (pyproject.toml) github.com/psf/black#configuration-format, needs to support as much options as Prettier's*, which is also an automatic formatter with no/minimal config, with the same goals, which include better/smaller git diffs. * prettier.io/docs/en/options.html , prettier.io/docs/en/configuration.html – Wis Mar 12 '20 at 16:10
  • 2
    It seems your team decided on 2-space indent for Python... IMO, that's a bad idea. (Believe me, I worked for a very large company which decided on that and lived to regret it.) Conservatively, 95%+ of the Python code you'll encounter will use 4-space indentation. Deviating from that means it'll be tricky to incorporate external libraries (consider cases where you're extending them for your needs and need to stay consistent with that style.) Exporting or open sourcing components is also harder if you're not following mainstream style. Onboarding new team members? Trouble. Just my 2¢. – filbranden Mar 12 '20 at 17:31
  • 2
    Insisting on deviating from a standard with near-universal adoption strikes me as the religiously-motivated action in this scenario. ;) Seriously, though, the front page docs of the plugin make it clear in a number of places that it is deliberately non-configurable and you either accept the choices they've made or "you're not ready to embrace Black yet". – B Layer Mar 13 '20 at 8:04

The whole point of Black is that it is not configurable. It calls itself "the uncompromising code formatter".

Its name comes from the Henry Ford quote about the Model T:

"any color you want, so long as it is Black".

In other words, you can indent any number of spaces that you want, so long as you want four.

Black is meant to eliminate all Git commits that only make style changes. You run Black automatically just before you commit, and it formats your code so that it looks just like everyone else's code.

Now nobody will go back and correct your code and change all of your single quotes ' to double quotes " or your two-space indents to four-space indents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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