Skip to content

Commit

Permalink
Add a google-java formatter.
Browse files Browse the repository at this point in the history
Fixes: #51

This commit adds a google-java-formatter. Some notes:
- Mostly a port from the internal version.
- I fixed a bug along the way, where if you didn't have clangformat
installed, codefmt would error-out during tab-complete.
- I fixed a typo in buildifier.
- And some minor updates to the README
  • Loading branch information
artasparks committed Jan 26, 2017
1 parent c38bd84 commit cad3527
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 10 deletions.
27 changes: 18 additions & 9 deletions README.md
Expand Up @@ -18,6 +18,7 @@ helpfiles in the `doc/` directory. The helpfiles are also available via
* Go (gofmt)
* [GN](https://www.chromium.org/developers/gn-build-configuration) (gn)
* HTML (js-beautify)
* Java (google-java-format or clang-format)
* JavaScript (clang-format)
* JSON (js-beautify)
* Proto (clang-format)
Expand Down Expand Up @@ -62,6 +63,7 @@ call vundle#end()
call glaive#Install()
" Optional: Enable codefmt's default mappings on the <Leader>= prefix.
Glaive codefmt plugin[mappings]
Glaive codefmt google_java_executable="java -jar /path/to/google-java-format-1.2-all-deps.jar"
```

Make sure you have updated maktaba recently. Codefmt depends upon maktaba
Expand All @@ -80,11 +82,19 @@ augroup autoformat_settings
autocmd FileType go AutoFormatBuffer gofmt
autocmd FileType gn AutoFormatBuffer gn
autocmd FileType html,css,json AutoFormatBuffer js-beautify
autocmd FileType java AutoFormatBuffer google-java-format
autocmd FileType python AutoFormatBuffer yapf
" Alternative: autocmd FileType python AutoFormatBuffer autopep8
augroup END
```

# Configuring formatters.

Most formatters have some options available that can be configured via
[Glaive](https://www.github.com/google/vim-glaive)
You can get a quick view of all codefmt flags by executing `:Glaive codefmt`, or
start typing flag names and use tab completion. See `:help Glaive` for usage
details.

# Installing and configuring formatters

Expand All @@ -99,31 +109,28 @@ trigger formatters via key mappings and/or autocommand hooks. See
vroom/main.vroom to learn more about formatting features, and see
vroom/FORMATTER-NAME.vroom to learn more about usage for individual formatters.

Most formatters have some options available that can be configured via Glaive.
You can get a quick view of all codefmt flags by executing `:Glaive codefmt`, or
start typing flag names and use tab completion. See `:help Glaive` for usage
details.

## Creating a New Formatter

Assume a filetype `myft` and a formatter called `MyFormatter`. Our detailed
guide to creating a formatter [lives
here](https://github.com/google/vim-codefmt/wiki/Formatter-Integration-Guide).

* Create an issue for your new formatter and discuss! Once there's consensus,
continue onward.
* Create an issue for your new formatter and discuss!

* Create a new file in `autoload/codefmt/myformatter.vim` See
`autoload/codefmt/buildifier.vim for an example. This is where all the
logic for formatting goes.

* Register the formatter with:
* Register the formatter in
[plugin/register.vim](https://github.com/google/vim-codefmt/blob/master/plugin/register.vim)
with:

```vim
call s:registry.AddExtension(codefmt#myformatter#GetFormatter())
```

* Create a flag in instant/flags.vim
* Create a flag in
[instant/flags.vim](https://github.com/Kashomon/vim-codefmt/blob/master/instant/flags.vim)

```vim
""
Expand All @@ -134,6 +141,8 @@ here](https://github.com/google/vim-codefmt/wiki/Formatter-Integration-Guide).
* Create a [vroom](https://github.com/google/vim-vroom) test named
`vroom/myformatter.vroom` to ensure your formatter works properly.

* Update the README.md to mention your new filetype!

That's it! Of course, the complicated step is in the details of
`myformatter.vim`.

Expand Down
4 changes: 4 additions & 0 deletions autoload/codefmt/clangformat.vim
Expand Up @@ -19,6 +19,10 @@ let s:plugin = maktaba#plugin#Get('codefmt')
function! s:ClangFormatHasAtLeastVersion(minimum_version) abort
if !exists('s:clang_format_version')
let l:executable = s:plugin.Flag('clang_format_executable')
if !executable(l:executable)
return 0
endif

let l:version_output =
\ maktaba#syscall#Create([l:executable, '--version']).Call().stdout
let l:version_string = matchstr(l:version_output, '\v\d+(.\d+)+')
Expand Down
72 changes: 72 additions & 0 deletions autoload/codefmt/googlejava.vim
@@ -0,0 +1,72 @@
" 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')

""
" @private
" Formatter: google-java-format
function! codefmt#googlejava#GetFormatter() abort
let l:formatter = {
\ 'name': 'google-java-format',
\ 'setup_instructions': 'Install google-java formatter ' .
\ "(https://github.com/google/google-java-format). \n" .
\ 'Enable with "Glaive codefmt google_java_executable=' .
\ '"java -jar /path/to/google-java-format-1.2-all-deps.jar" ' .
\ 'in your vimrc' }

function l:formatter.IsAvailable() abort
let l:exec = s:plugin.Flag('google_java_executable')
if executable(l:exec)
return 1
elseif !empty(l:exec) && l:exec isnot# 'google-java-format'
" The user has specified a custom formatter command. Hope it works.
" /shrug.
return 1
else
return 0
endif
endfunction

function l:formatter.AppliesToBuffer() abort
return &filetype is# 'java'
endfunction

""
" Reformat the current buffer using java-format, only targeting {ranges}.
function l:formatter.FormatRanges(ranges) abort
if empty(a:ranges)
return
endif
" Split the command on spaces, except when there's a proceeding \
let l:cmd = split(s:plugin.Flag('google_java_executable'), '\\\@<! ')
for [l:startline, l:endline] in a:ranges
call maktaba#ensure#IsNumber(l:startline)
call maktaba#ensure#IsNumber(l:endline)
endfor
let l:ranges_str = join(map(a:ranges, 'v:val[0] . ":" . v:val[1]'), ',')
let l:cmd += ['--lines', l:ranges_str, '-']

let l:input = join(getline(1, line('$')), "\n")
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
let l:formatted = split(l:result.stdout, "\n")
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
endfunction

let s:google_java_format = l:formatter
return l:formatter
endfunction


6 changes: 6 additions & 0 deletions instant/flags.vim
Expand Up @@ -87,3 +87,9 @@ call s:plugin.Flag('gn_executable', 'gn')
""
" The path to the buildifier executable.
call s:plugin.Flag('buildifier_executable', 'buildifier')

""
" The path to the google-java executable. Generally, this should have the
" form:
" `java -jar /path/to/google-java`
call s:plugin.Flag('google_java_executable', 'google-java-format')
1 change: 1 addition & 0 deletions plugin/register.vim
Expand Up @@ -29,3 +29,4 @@ call s:registry.AddExtension(codefmt#yapf#GetFormatter())
call s:registry.AddExtension(codefmt#autopep8#GetFormatter())
call s:registry.AddExtension(codefmt#gn#GetFormatter())
call s:registry.AddExtension(codefmt#buildifier#GetFormatter())
call s:registry.AddExtension(codefmt#googlejava#GetFormatter())
2 changes: 1 addition & 1 deletion vroom/buildifier.vroom
Expand Up @@ -15,7 +15,7 @@ examples.
:call codefmt#SetWhetherToPerformIsAvailableChecksForTesting(0)


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

% foo_library(name = "foo", srcs = ["bar.js"],)
Expand Down
57 changes: 57 additions & 0 deletions vroom/googlejava.vroom
@@ -0,0 +1,57 @@
The built-in google-java formatter knows how to format Java BUILD files. 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 google-java formatter expects a google-java executable to be installed on
your system.

% class Foo { public String getFoo() { return "bar"; } }
:FormatCode google-java-format
! google-java-format .*
$ class Foo {
$ public String getFoo() {
$ return "bar";
$ }
$ }

The name or path of the google-java executable can be configured via the
google_java_executable flag if the default of "google-java" doesn't work.

:Glaive codefmt google_java_executable='java -jar /path/to/google-java.jar'
:FormatCode google-java-format
! java -jar /path/to/google-java.jar .*
$ class Foo {
$ public String getFoo() {
$ return "bar";
$ }
$ }
:Glaive codefmt google_java_executable='google-java-format'

The java filetype will use the google-java formatter by default.

@clear
% class Foo { public String getFoo() { return "bar"; } }

:set filetype=java
:FormatCode
! google-java-format .*
$ class Foo {
$ public String getFoo() {
$ return "bar";
$ }
$ }

:set filetype=

0 comments on commit cad3527

Please sign in to comment.