Skip to content

Commit

Permalink
Add ruff as formatter for Python
Browse files Browse the repository at this point in the history
  • Loading branch information
dbarnett authored and snu5mumr1k committed Aug 25, 2024
1 parent 6fa1616 commit 123b4de
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ codefmt` if codefmt is installed (and helptags have been generated).
* Nix (nixpkgs-fmt)
* OCaml ([ocamlformat](https://github.com/ocaml-ppx/ocamlformat))
* Protocol Buffers (clang-format)
* Python (Autopep8, Black, isort, or YAPF)
* Python (Autopep8, Black, isort, Ruff, or YAPF)
* Ruby ([rubocop](https://rubocop.org))
* Rust ([rustfmt](https://github.com/rust-lang/rustfmt))
* Shell (shfmt)
Expand Down
71 changes: 71 additions & 0 deletions autoload/codefmt/ruff.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
" Copyright 2017 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')


function! s:FormatWithArgs(args) abort
let l:executable = s:plugin.Flag('ruff_executable')
let l:lines = getline(1, line('$'))
let l:cmd = [l:executable, 'format'] + a:args
if !empty(@%)
let l:cmd += ['--stdin-filename=' . @%]
endif
let l:input = join(l:lines, "\n")
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call(0)
if v:shell_error
call maktaba#error#Shout('Error formatting file: %s', l:result.stderr)
return
endif
let l:formatted = split(l:result.stdout, "\n")

call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
endfunction


""
" @private
" Formatter: ruff
function! codefmt#ruff#GetFormatter() abort
let l:formatter = {
\ 'name': 'ruff',
\ 'setup_instructions': 'Install ruff ' .
\ '(https://docs.astral.sh/ruff/).'}

function l:formatter.IsAvailable() abort
return executable(s:plugin.Flag('ruff_executable'))
endfunction

function l:formatter.AppliesToBuffer() abort
return codefmt#formatterhelpers#FiletypeMatches(&filetype, 'python')
endfunction

function l:formatter.Format() abort
call s:FormatWithArgs([])
endfunction

""
" Reformat the current buffer with ruff or the binary named in
" @flag(ruff_executable), only targeting the range between {startline} and
" {endline}.
" @throws ShellError
function l:formatter.FormatRange(startline, endline) abort
call maktaba#ensure#IsNumber(a:startline)
call maktaba#ensure#IsNumber(a:endline)
call s:FormatWithArgs(['--range=' . a:startline . ':' . a:endline])
endfunction

return l:formatter
endfunction
6 changes: 5 additions & 1 deletion doc/codefmt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The current list of defaults by filetype is:
* lua: luaformatterfiveone
* nix: nixpkgs-fmt
* ocaml: ocamlformat
* python: autopep8, black, yapf
* python: autopep8, black, ruff, yapf
* ruby: rubocop
* rust: rustfmt
* sh: shfmt
Expand Down Expand Up @@ -98,6 +98,10 @@ The path to the mix executable for Elixir. String, list, or callable that
takes no args and returns a string or a list with command line arguments.
Default: 'mix' `

*codefmt:ruff_executable*
The path to the ruff executable.
Default: 'ruff' `

*codefmt:yapf_executable*
The path to the yapf executable.
Default: 'yapf' `
Expand Down
4 changes: 4 additions & 0 deletions instant/flags.vim
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ call s:plugin.Flag('js_beautify_executable', 'js-beautify')
" takes no args and returns a string or a list with command line arguments.
call s:plugin.Flag('mix_executable', 'mix')

""
" The path to the ruff executable.
call s:plugin.Flag('ruff_executable', 'ruff')

""
" The path to the yapf executable.
call s:plugin.Flag('yapf_executable', 'yapf')
Expand Down
3 changes: 2 additions & 1 deletion plugin/register.vim
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
" * lua: luaformatterfiveone
" * nix: nixpkgs-fmt
" * ocaml: ocamlformat
" * python: autopep8, black, yapf
" * python: autopep8, black, ruff, yapf
" * ruby: rubocop
" * rust: rustfmt
" * sh: shfmt
Expand Down Expand Up @@ -82,6 +82,7 @@ call s:registry.AddExtension(codefmt#nixpkgs_fmt#GetFormatter())
call s:registry.AddExtension(codefmt#autopep8#GetFormatter())
call s:registry.AddExtension(codefmt#isort#GetFormatter())
call s:registry.AddExtension(codefmt#black#GetFormatter())
call s:registry.AddExtension(codefmt#ruff#GetFormatter())
call s:registry.AddExtension(codefmt#yapf#GetFormatter())
call s:registry.AddExtension(codefmt#rubocop#GetFormatter())
call s:registry.AddExtension(codefmt#rustfmt#GetFormatter())
Expand Down
71 changes: 71 additions & 0 deletions vroom/ruff.vroom
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
The built-in ruff 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(...)<CR>
| call add(g:repeat_calls, a:000)<CR>
:endfunction
:call maktaba#test#Override('repeat#set', 'FakeRepeat')

:call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0)


The ruff formatter expects the ruff executable to be installed on your
system.

:silent file somefile.py
% f()
:FormatCode ruff
! ruff format --stdin-filename=somefile.py.*
$ f()

The name or path of the ruff executable can be configured via the
ruff_executable flag if the default of "ruff" doesn't work.

:Glaive codefmt ruff_executable='/somepath/ruff'
:FormatCode ruff
! /somepath/ruff format.*
$ f()
:Glaive codefmt ruff_executable='ruff'


You can format any buffer with ruff specifying the formatter explicitly.

@clear
% if True: pass

:FormatCode ruff
! ruff format.*
$ if True:
$ pass
if True:
pass
@end

It can format specific line ranges of code using :FormatLines.

@clear
% some_tuple=( 1,2, 3,'a' );<CR>
|if bar : bar+=1; bar=bar* bar<CR>
|else: bar-=1;

:2,3FormatLines ruff
! ruff format .*--range=2:3.*
$ 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

0 comments on commit 123b4de

Please sign in to comment.