vscode-black-formatter: More gracefully handle the fact that Black does not support "Format Selection"

Environment data

  • VS Code version: 1.23.1
  • Extension version (available under the Extensions sidebar): 2018.5.0
  • OS and version: Windows 10 x64
  • Python version (& distribution if applicable, e.g. Anaconda): python 3.6.3 x64
  • Type of virtual environment used (N/A | venv | virtualenv | conda | …): n/a
  • Relevant/affected Python packages and their versions: black 18.6b1

Actual behavior

Every single time a paste a piece of code, I get the error message: “Black does not support the “Format Selection” command”

Expected behavior

No error message pop-ups.

    "editor.formatOnPaste": true,
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "editor.tabSize": 3,
    "python.formatting.autopep8Args": [
        "--indent_size=3"
    ],
    //"python.formatting.blackArgs": [
    //    "--indent_size=3"
    //],
    "python.formatting.provider": "black",
    "python.linting.pep8Enabled": false,
    "python.linting.pep8Args": [
        "--ignore=E111,E114,E121,E126,E127,E128,E265,E231,E303,E501,W291,W293,W503",
        "--max-line-length=89"
    ],
    //"python.linting.pylintArgs" If you don't use the pylintrc config file:
    //"python.linting.pylintArgs": ["--disable=C0303,W0311,E1101"],
    "python.linting.pylintEnabled": true,
    "python.linting.pydocstyleEnabled": false,

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 56
  • Comments: 45 (16 by maintainers)

Most upvoted comments

I should also mention that to turn off any feature in VS Code just for Python, you can do:

"[python]": {
    "editor.formatOnPaste": false
}

@brettcannon Thanks for your answer but, please note that my original issue was not what this ticket has become now. I can see why Black does not want to do partial formatting. It would be nice if it allowed the option, but I can live with it.

My issue is with the Python Extension popping up an error window every single time I do a paste.

Also, the issue ticket is currently closed, so the re-orientation won’t lead to anything. Maybe either one of us should open a new ticket to address our respective problem.

@brettcannon @d3r3kk Suggestions

  • Change the message from Black does not support the "Format Selection" command to Black does not support the "Format Selection" command and "Format on Paste" feature
  • Add a button Disable format on paste to the above message.
  • Add a button Do not show this again to the above message.

That’s by design from Black itself, so you will have to convince the Black project to support partial formatting (which they have said they don’t want to).

The latest VS Code allows the users to configure the formatting for the entire file or line of code changed, so many sure to enable the editor.formatOnSaveMode as file in the settings

{
  "python.formatting.provider": "black",
  "[python]": {
    "editor.formatOnPaste": false,
    "editor.formatOnSaveMode": "file"
  }
}

Maybe we can detect when people turn on Black but have editor.formatOnPaste turned on and give a notification that they should consider turning it off for Python (e.g. link to the docs once they are updated with how to do this)?

Why don’t we modify the warning notification to provide an option to disable formatOnPaste just for Python when they happen to have the setting turned on.

Since we already have blackd, we’ll teach it the LSP protocol.

@brettcannon, we are considering adding this to Black to decrease the need to use alternative formatters in editor integration. How does VScode request a code region to be formatted? How is Black supposed to return the formatted code?

It would be easiest if we’d still get the entire file with a line range which would enable us to fare better with partially selected expressions. Then we’d just emit the entire file back as usual.

You could use Darker to only do Black reformatting for those lines which have been modified since the last commit (or e.g. relative to a given branch).

The documentation has instructions for integration with VS Code.

See this blog post for a detailed example of what Darker does.

@brettcannon Have you thought about implementing a custom partial-formatting, via expanding selection to full lines and moving the contained code to a temporary file for black to handle as e.g. described here https://blog.godatadriven.com/black-formatting-selection?

As black’s formatting is AST-based, selecting code that is not valid python by its own right will fail, however I think that is not too much of a drawback and could just result in a pop up like failed to reformat.

This might be a different discussion, but @brettcannon & @DonJayamanne what do you think about allowing the configuration of a different formatter for formatOnPaste? That way black can be the main formatter used for the file, but you could still use one of the formatters that does format selections just for paste.

Hi, an extension of this issue now happens with the move to a separate extension. If I try to format a selection or to format modified lines I get the following popup:

image

I think this message is very confusing and that the previous message saying that black does not support “Format selection” should be shown instead.

Here’s a first stab: https://github.com/psf/black/pull/2512 Note: this currently just implements textDocument/formatting, but I’d appreciate a review as I’m not intimate with the LSP spec. textDocument/rangeFormatting TBD after this.

@codingbrowny people specifically want Black in this issue, so changing the formatter to autopep8 won’t fix the issue.

@akaihola we have some ideas on how to at least make it easier for people to create their own formatting extension, so hopefully that will allow someone to create a Darker extension. But unfortunately Darker isn’t popular enough right now for us to want to rely on it for something as critical as formatting support.

@ambv @zsol @psf I would really love to see this change in Black. Really tired of this notification! Screen Shot 2020-09-19 at 8 42 59 AM

Edit: Setting the below param in Settings.json disabled the problem, but still that would be a good feature to have in the future FYI.

"[python]": {
    "editor.formatOnPaste": false
}

There’s actually a way to do that:

  1. Save $theFile prior to changes in /tmp/a.
  2. Store diff between $theFile and /tmp/a.
  3. black $theFile
  4. Unpatch diff to $theFile

Surely it won’t work in all cases, but should do the trick for many.

There should be a global option IMHO that tells vscode what to do when a formatter doesn’t support partial formatting: no format, format whole file, smartypants-format (above process) or no-format if fails, smartypants-format or format-whole-file if fails.

Maybe I’m off the track, But wouldn’t it be better if we change the internal logic to reformat the whole file on paste?

I cannot reproduce this behaviour:

I got the same spammy notification from black even though I’m using “python.formatting.provider”: “autopep8”.

verify_autopep8_doesnt_show_black_warning_line_format

Removing needs verification label.

@zephyrite I can’t reproduce the error message when autopep8 is the chosen formatter:

"python.formatting.provider": "autopep8",
"editor.formatOnPaste": true

Did you perhaps try out Black and then flip your setting back to autopep8 without saving initially?

@luabud Hey I’d like to work on this as part of GHC OSD. For this issue, I need to change the message to the previous message saying that black does not support “Format selection”. Is that correct?

I like Don’s solution:

  • Change the message to Black does not support the "Format Selection" command and "Format on Paste" feature

  • Add a button “Disable format on paste”

    • This should disable format on paste for Python only: "[python]": { "editor.formatOnPaste": false }
  • Add a button “Do not show again”

If anyone would like to submit a PR for this, the team will be more than happy to review it 😊 otherwise at the moment this is not as much as a high priority for the team to work on.

@nnja it’s definitely possible, but I don’t if that is a better solution as that’s extra configuration and installing versus saying “the tool you chose doesn’t let you do that”.