diff --git a/README.md b/README.md index 1d3ccf3..0b3b8ba 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ helpfiles in the `doc/` directory. The helpfiles are also available via * JavaScript (clang-format or [prettier](https://prettier.io)) * JSON (js-beautify) * Proto (clang-format) -* Python (Autopep8 or YAPF) +* Python (Autopep8, Black, or YAPF) * Rust ([rustfmt](https://github.com/rust-lang/rustfmt)) * TypeScript (clang-format) * Shell (shfmt) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index fd6a3b5..3724f19 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -33,7 +33,7 @@ " * fish: fish_indent " * gn: gn " * go: gofmt -" * python: autopep8, yapf +" * python: autopep8, black, yapf let s:plugin = maktaba#plugin#Get('codefmt') diff --git a/autoload/codefmt/black.vim b/autoload/codefmt/black.vim new file mode 100644 index 0000000..a8f0628 --- /dev/null +++ b/autoload/codefmt/black.vim @@ -0,0 +1,51 @@ +" Copyright 2020 Google Inc. All rights reserved. +" +" Licensed under the Apache License, Version 2.0 (the "License"); +" you may not use this file except in compliance with the License. +" You may obtain a copy of the License at +" +" http://www.apache.org/licenses/LICENSE-2.0 +" +" Unless required by applicable law or agreed to in writing, software +" distributed under the License is distributed on an "AS IS" BASIS, +" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +" See the License for the specific language governing permissions and +" limitations under the License. + + +let s:plugin = maktaba#plugin#Get('codefmt') + + +"" +" @private +" Formatter: black +function! codefmt#black#GetFormatter() abort + let l:formatter = { + \ 'name': 'black', + \ 'setup_instructions': 'Install black ' . + \ '(https://pypi.python.org/pypi/black/).'} + + function l:formatter.IsAvailable() abort + return executable(s:plugin.Flag('black_executable')) + endfunction + + function l:formatter.AppliesToBuffer() abort + return &filetype is# 'python' + endfunction + + "" + " Reformat the current buffer with black or the binary named in + " @flag(black_executable) + " + " We implement Format(), and not FormatRange{,s}(), because black doesn't + " provide a hook for formatting a range + function l:formatter.Format() abort + let l:executable = s:plugin.Flag('black_executable') + + call codefmt#formatterhelpers#Format([ + \ l:executable, + \ '-']) + endfunction + + return l:formatter +endfunction diff --git a/doc/codefmt.txt b/doc/codefmt.txt index 72db9ab..66c5807 100644 --- a/doc/codefmt.txt +++ b/doc/codefmt.txt @@ -53,6 +53,10 @@ Default: 'dartfmt' ` The path to the js-beautify executable. Default: 'js-beautify' ` + *codefmt:black_executable* +The path to the black executable. +Default: 'black' ` + *codefmt:yapf_executable* The path to the yapf executable. Default: 'yapf' ` @@ -162,7 +166,7 @@ The current list of defaults by filetype is: * fish: fish_indent * gn: gn * go: gofmt - * python: autopep8, yapf + * python: autopep8, black, yapf ============================================================================== DICTIONARIES *codefmt-dicts* diff --git a/instant/flags.vim b/instant/flags.vim index 0ea46f7..5550030 100644 --- a/instant/flags.vim +++ b/instant/flags.vim @@ -83,6 +83,10 @@ call s:plugin.Flag('js_beautify_executable', 'js-beautify') " The path to the yapf executable. call s:plugin.Flag('yapf_executable', 'yapf') +"" +" The path to the black executable. +call s:plugin.Flag('black_executable', 'black') + "" " The path to the gn executable. call s:plugin.Flag('gn_executable', 'gn') diff --git a/plugin/register.vim b/plugin/register.vim index 91b5c52..1770f4c 100644 --- a/plugin/register.vim +++ b/plugin/register.vim @@ -29,6 +29,7 @@ call s:registry.AddExtension(codefmt#jsbeautify#GetFormatter()) call s:registry.AddExtension(codefmt#clangformat#GetFormatter()) call s:registry.AddExtension(codefmt#gofmt#GetFormatter()) call s:registry.AddExtension(codefmt#dartfmt#GetFormatter()) +call s:registry.AddExtension(codefmt#black#GetFormatter()) call s:registry.AddExtension(codefmt#yapf#GetFormatter()) call s:registry.AddExtension(codefmt#autopep8#GetFormatter()) call s:registry.AddExtension(codefmt#gn#GetFormatter()) diff --git a/vroom/black.vroom b/vroom/black.vroom new file mode 100644 index 0000000..2d9f555 --- /dev/null +++ b/vroom/black.vroom @@ -0,0 +1,71 @@ +The built-in black formatter knows how to format python code. +If you aren't familiar with basic codefmt usage yet, see main.vroom first. + +We'll set up codefmt and configure the vroom environment, then jump into some +examples. + + :source $VROOMDIR/setupvroom.vim + + :let g:repeat_calls = [] + :function FakeRepeat(...) + | call add(g:repeat_calls, a:000) + :endfunction + :call maktaba#test#Override('repeat#set', 'FakeRepeat') + + :call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0) + + +The black formatter expects the black executable to be installed on your +system. + + % f() + :FormatCode black + ! black .* + $ f() + +The name or path of the black executable can be configured via the +black_executable flag if the default of "black" doesn't work. + + :Glaive codefmt black_executable='blackpy3' + :FormatCode black + ! blackpy3 .* + $ f() + :Glaive codefmt black_executable='black' + + +You can format any buffer with black specifying the formatter explicitly. +Here's an example: + + @clear + % if True: pass + + :FormatCode black + ! black .* + $ if True: + $ pass + if True: + pass + @end + +Here's a second example: + + @clear + % some_tuple=( 1,2, 3,'a' ); + |if bar : bar+=1; bar=bar* bar + |else: bar-=1; + + :FormatCode black + ! black .* + $ some_tuple = (1, 2, 3, "a"); + $ if bar: + $ bar += 1 + $ bar = bar * bar + $ else: + $ bar -= 1 + some_tuple = (1, 2, 3, "a"); + if bar: + bar += 1 + bar = bar * bar + else: + bar -= 1 + @end