-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option to apply on an indented fragment of Python code (e.g. a single method) #1352
Comments
For reference, Vim binding to call Black on the visual selection:
|
If indentation seems to be the only problem here not allowing to perform black as intended, then a wrapper script using This can obviously be integrated in black through some argument (or maybe natively!) using the same logic. |
I wrote a wrapper script to do the dedenting/reindenting: https://github.com/tartley/dotfiles/blob/master/other/bin/enblacken (I don't think It's rough and ready, |
For emac users, there is https://github.com/wbolster/emacs-python-black (according to #1076 (comment)) See also https://github.com/wbolster/black-macchiato (according to #987 (comment) and #1076 (comment)) I haven't verified that either of these options actually work. |
I don't understand @ichard26, you just closed all issues that asked for "Format Selection" including mine! All of them were saying the same thing but in different situations: one asked for a cli option, for me (#987) I asked for running it against some visualized lines in vim, other one asked for running in vscode, All of them are the same. Is it going somewhere anysoon? Can I help to achieve this functionality? |
Due to microsoft/vscode-black-formatter#176 we should tackle this soonish. |
Darker is a tool which applies Black reformatting only to lines it detects as having been modified after the latest commit (or since a given commit, or between given commits). The way Darker does it is:
In some edge cases, it is not possible to reliably detect which areas in the file before reformatting correspond to reformatted blocks. In that case, Darker extends the diff regions until the AST verification succeeds. This is done using bisection to quickly find the smallest successful region. For those interested, the essential parts of this algorithm are in Doing all this would be much simpler if Black indeed grew the capability to reformat partial files! Steps 3–8 could be replaced with a simple request for Black to reformat the given line range. So I'm excited about this – and the fact that the decision to not support line ranges (in comment from @ambv in microsoft/vscode-python#134 in Apr 2018) has been reversed. 👍 |
Also, as I mentioned in microsoft/vscode-black-formatter#176, Darker can already act as a drop-in replacement for Black as a code formatter in VSCode (and various other IDEs, see Editor integration in the README). Currently, when using Darker as a formatter, essentially VSCode will reformat code (either with a shortcut, after a delay or after saving) but leave unmodified regions intact. So if Black should decide to not implement reformatting of a given line range after all, we could add e.g. a |
You may also be interested in https://github.com/google/yapf/blob/main/yapf/third_party/yapf_diff/yapf_diff.py as a reference or even its own tool, it is a stand alone little script to take a diff as input and use that to drive a tool (ie: a formatter accepting one or more All the algorithms used for this that i've seen use basically the same obvious tactic: process a diff to discover the input file regions of interest, only accept changes that land within those (anchored to original input file line numbers) line ranges. |
Curious, what is the status on the "reformatting of given line range(s)" support in Black? I've also read microsoft/vscode-black-formatter#176 and #2883, and there is now a |
As an out-of-the-blue idea I just had, for specifically the case of formatting an indented block, what if we just reproduced the indentation for black, instead of trying to dedent before and re-indent later? For instance suppose I want to reformat the section marked below: class Something(Other):
def method(self, some_parameter):
try:
# The code selection starts on the line below
if condition:
self.do_something_else_with_parameters({
'complex-structure': 'containing values', 'some other key':
some_parameter})
# The code selection ends on the line above
finally:
self.do_some_cleanup() We could sent to if indent_level_1:
if indent_level_2:
if indent_level_3: # START
if condition:
self.do_something_else_with_parameters({
'complex-structure': 'containing values', 'some other key':
some_parameter}) Whatever This should work for any python fragment if it contains complete statements (i.e. if the fragment contains a And detecting how many levels of indentation are needed should be easy from the first line of the fragment, again, as long as it contains complete statements. |
FYI-- We have patches that implement this feature (in the Pyink fork via the (Before that though, I need to fix microsoft/vscode-python#3438 since the implementation relies it.) |
Closing since now we have #4020! |
My problem is that sometimes I'm editing some code in a project that doesn't use Black (heresy, I know). Sometimes I'll type some code, or paste into the source something like a generated dict literal, and I want to run Black on just the edited section of code.
I set up a Vim binding to do that, passing just the code from the visual selection to Black, and using the output to update the code in Vim. The result is:
What I'd like to see:
The alternative I'm currently considering is writing my own wrapper script to do the un-indenting and re-indenting. Not a biggie, but I thought other people might appreciate this mode of operation being supported out of the box.
The text was updated successfully, but these errors were encountered: