Skip to content

Commit 2393184

Browse files
committed
Implement common helper functions for common formatting operations
1 parent ff5212a commit 2393184

10 files changed

+112
-83
lines changed

autoload/codefmt/autopep8.vim

+8-19
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,18 @@ function! codefmt#autopep8#GetFormatter() abort
6767

6868
call maktaba#ensure#IsNumber(a:startline)
6969
call maktaba#ensure#IsNumber(a:endline)
70-
let l:lines = getline(1, line('$'))
7170

7271
if s:autopep8_supports_range
73-
let l:cmd = [l:executable, '--range', ''.a:startline, ''.a:endline, '-']
74-
let l:input = join(l:lines, "\n")
72+
call codefmt#formatterhelpers#Format(maktaba#syscall#Create([
73+
\ l:executable,
74+
\ '--range', string(a:startline), string(a:endline),
75+
\ '-']))
7576
else
76-
let l:cmd = [l:executable, '-']
77-
" Hack range formatting by formatting range individually, ignoring context.
78-
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
77+
call codefmt#formatterhelpers#AttemptFakeRangeFormatting(
78+
\ a:startline,
79+
\ a:endline,
80+
\ maktaba#syscall#Create([l:executable, '-']))
7981
endif
80-
81-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
82-
let l:formatted = split(l:result.stdout, "\n")
83-
84-
if s:autopep8_supports_range
85-
let l:full_formatted = l:formatted
86-
else
87-
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
88-
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
89-
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
90-
endif
91-
92-
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
9382
endfunction
9483

9584
return l:formatter

autoload/codefmt/buildifier.vim

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ function! codefmt#buildifier#GetFormatter() abort
4747

4848
let l:input = join(getline(1, line('$')), "\n")
4949
try
50-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
51-
let l:formatted = split(l:result.stdout, "\n")
52-
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
50+
" NOTE: Ignores any line ranges given and formats entire buffer.
51+
" buildifier does not support range formatting.
52+
call codefmt#formatterhelpers#Format(l:cmd)
5353
catch
5454
" Parse all the errors and stick them in the quickfix list.
5555
let l:errors = []

autoload/codefmt/dartfmt.vim

+6-15
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,12 @@ function! codefmt#dartfmt#GetFormatter() abort
3838
" @flag(dartfmt_executable}, only targetting the range from {startline} to
3939
" {endline}
4040
function l:formatter.FormatRange(startline, endline) abort
41-
" Hack range formatting by formatting range individually, ignoring context.
4241
let l:cmd = [ s:plugin.Flag('dartfmt_executable') ]
43-
" TODO When https://github.com/dart-lang/dart_style/issues/92 is implemented
44-
" use those options.
45-
call maktaba#ensure#IsNumber(a:startline)
46-
call maktaba#ensure#IsNumber(a:endline)
47-
let l:lines = getline(1, line('$'))
48-
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
4942
try
50-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
51-
let l:formatted = split(l:result.stdout, "\n")
52-
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
53-
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
54-
55-
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
56-
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
43+
" dartfmt does not support range formatting yet:
44+
" https://github.com/dart-lang/dart_style/issues/92
45+
call codefmt#formatterhelpers#AttemptFakeRangeFormatting(
46+
\ a:startline, a:endline, maktaba#syscall#Create(l:cmd))
5747
catch /ERROR(ShellError):/
5848
" Parse all the errors and stick them in the quickfix list.
5949
let l:errors = []
@@ -71,7 +61,8 @@ function! codefmt#dartfmt#GetFormatter() abort
7161

7262
if empty(l:errors)
7363
" Couldn't parse dartfmt error format; display it all.
74-
call maktaba#error#Shout('Failed to format range; showing all errors: %s', v:exception)
64+
call maktaba#error#Shout(
65+
\ 'Failed to format range; showing all errors: %s', v:exception)
7566
else
7667
let l:errorHeaderLines = split(v:exception, "\n")[1 : 5]
7768
let l:errorHeader = join(l:errorHeaderLines, "\n")

autoload/codefmt/formatterhelpers.vim

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
" Copyright 2017 Google Inc. All rights reserved.
2+
"
3+
" Licensed under the Apache License, Version 2.0 (the "License");
4+
" you may not use this file except in compliance with the License.
5+
" You may obtain a copy of the License at
6+
"
7+
" http://www.apache.org/licenses/LICENSE-2.0
8+
"
9+
" Unless required by applicable law or agreed to in writing, software
10+
" distributed under the License is distributed on an "AS IS" BASIS,
11+
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
" See the License for the specific language governing permissions and
13+
" limitations under the License.
14+
15+
16+
""
17+
" @public
18+
" Format lines in the current buffer via a formatter invoked by {cmd}. The
19+
" command includes the explicit range line numbers to use, if any.
20+
"
21+
" @throws ShellError if the {cmd} system call fails
22+
function! codefmt#formatterhelpers#Format(cmd) abort
23+
let l:lines = getline(1, line('$'))
24+
let l:input = join(l:lines, "\n")
25+
26+
let l:result = maktaba#syscall#Create(a:cmd).WithStdin(l:input).Call()
27+
let l:formatted = split(l:result.stdout, "\n")
28+
29+
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
30+
endfunction
31+
32+
""
33+
" @public
34+
" Attempt to format a range of lines from {startline} to {endline} in the
35+
" current buffer via a formatter that doesn't natively support range
36+
" formatting (invoked by {cmd}), using a hacky strategy of sending those lines
37+
" to the formatter in isolation.
38+
"
39+
" If invoking this hack, please make sure to file a feature request against
40+
" the tool for range formatting and post a URL for that feature request above
41+
" code that calls it.
42+
"
43+
" @throws ShellError if the {cmd} system call fails
44+
function! codefmt#formatterhelpers#AttemptFakeRangeFormatting(
45+
\ startline, endline, cmd) abort
46+
call maktaba#ensure#IsNumber(a:startline)
47+
call maktaba#ensure#IsNumber(a:endline)
48+
49+
let l:lines = getline(1, line('$'))
50+
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
51+
52+
let l:result = a:cmd.WithStdin(l:input).Call()
53+
let l:formatted = split(l:result.stdout, "\n")
54+
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
55+
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
56+
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
57+
58+
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
59+
endfunction

autoload/codefmt/gofmt.vim

+4-12
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,12 @@ function! codefmt#gofmt#GetFormatter() abort
3838
" @flag(gofmt_executable), only targeting the range between {startline} and
3939
" {endline}.
4040
function l:formatter.FormatRange(startline, endline) abort
41-
" Hack range formatting by formatting range individually, ignoring context.
4241
let l:cmd = [ s:plugin.Flag('gofmt_executable') ]
43-
call maktaba#ensure#IsNumber(a:startline)
44-
call maktaba#ensure#IsNumber(a:endline)
45-
let l:lines = getline(1, line('$'))
46-
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
4742
try
48-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
49-
let l:formatted = split(l:result.stdout, "\n")
50-
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
51-
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
52-
53-
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
54-
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
43+
" gofmt does not support range formatting.
44+
" TODO: File a feature request with gofmt and link it here.
45+
call codefmt#formatterhelpers#AttemptFakeRangeFormatting(
46+
\ a:startline, a:endline, maktaba#syscall#Create(l:cmd))
5547
catch /ERROR(ShellError):/
5648
" Parse all the errors and stick them in the quickfix list.
5749
let l:errors = []

autoload/codefmt/googlejava.vim

+1-4
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ function! codefmt#googlejava#GetFormatter() abort
5959
let l:ranges_str = join(map(copy(a:ranges), 'v:val[0] . ":" . v:val[1]'), ',')
6060
let l:cmd += ['--lines', l:ranges_str, '-']
6161

62-
let l:input = join(getline(1, line('$')), "\n")
63-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
64-
let l:formatted = split(l:result.stdout, "\n")
65-
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
62+
call codefmt#formatterhelpers#Format(maktaba#syscall#Create(l:cmd))
6663
endfunction
6764

6865
return l:formatter

autoload/codefmt/jsbeautify.vim

+4-11
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,10 @@ function! codefmt#jsbeautify#GetFormatter() abort
5252
call maktaba#ensure#IsNumber(a:startline)
5353
call maktaba#ensure#IsNumber(a:endline)
5454

55-
let l:lines = getline(1, line('$'))
56-
" Hack range formatting by formatting range individually, ignoring context.
57-
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
58-
59-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
60-
let l:formatted = split(l:result.stdout, "\n")
61-
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
62-
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
63-
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
64-
65-
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
55+
" js-beautify does not support range formatting yet:
56+
" https://github.com/beautify-web/js-beautify/issues/610
57+
call codefmt#formatterhelpers#AttemptFakeRangeFormatting(
58+
\ a:startline, a:endline, maktaba#syscall#Create(l:cmd))
6659
endfunction
6760

6861
return l:formatter

autoload/codefmt/rustfmt.vim

+2-5
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,10 @@ function! codefmt#rustfmt#GetFormatter() abort
5252

5353
call extend(l:cmd, l:rustfmt_options)
5454
try
55-
let l:lines = getline(1, line('$'))
56-
let l:input = join(l:lines, "\n")
57-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
58-
let l:formatted = split(l:result.stdout, "\n")
55+
" NOTE: Ignores any line ranges given and formats entire buffer.
5956
" Even though rustfmt supports formatting ranges through the --file-lines
6057
" flag, it is not still enabled in the stable binaries.
61-
call maktaba#buffer#Overwrite(1, line('$'), l:formatted)
58+
call codefmt#formatterhelpers#Format(l:cmd)
6259
catch /ERROR(ShellError):/
6360
" Parse all the errors and stick them in the quickfix list.
6461
let l:errors = []

autoload/codefmt/shfmt.vim

+6-14
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,14 @@ function! codefmt#shfmt#GetFormatter() abort
4848
\ 'shfmt_options flag must be list or callable. Found %s',
4949
\ string(l:Shfmt_options))
5050
endif
51-
" Hack range formatting by formatting range individually, ignoring context.
52-
" Feature request for range formatting:
53-
" https://github.com/mvdan/sh/issues/333
5451
let l:cmd = [ s:plugin.Flag('shfmt_executable') ] + l:shfmt_options
55-
call maktaba#ensure#IsNumber(a:startline)
56-
call maktaba#ensure#IsNumber(a:endline)
57-
let l:lines = getline(1, line('$'))
58-
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
5952
try
60-
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
61-
let l:formatted = split(l:result.stdout, "\n")
62-
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
63-
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
64-
65-
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
66-
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
53+
" Feature request for range formatting:
54+
" https://github.com/mvdan/sh/issues/333
55+
call codefmt#formatterhelpers#AttemptFakeRangeFormatting(
56+
\ a:startline,
57+
\ a:endline,
58+
\ maktaba#syscall#Create(l:cmd))
6759
catch /ERROR(ShellError):/
6860
" Parse all the errors and stick them in the quickfix list.
6961
let l:errors = []

doc/codefmt.txt

+19
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,25 @@ codefmt#FormatMap({type}) *codefmt#FormatMap()*
211211
Suitable for use as 'operatorfunc'; see |g@| for details. The type is
212212
ignored since formatting only works on complete lines.
213213

214+
codefmt#formatterhelpers#Format({cmd}) *codefmt#formatterhelpers#Format()*
215+
Format lines in the current buffer via a formatter invoked by {cmd}. The
216+
command includes the explicit range line numbers to use, if any.
217+
218+
Throws ERROR(ShellError) if the {cmd} system call fails
219+
220+
codefmt#formatterhelpers#AttemptFakeRangeFormatting({startline}, {endline},
221+
{cmd}) *codefmt#formatterhelpers#AttemptFakeRangeFormatting()*
222+
Attempt to format a range of lines from {startline} to {endline} in the
223+
current buffer via a formatter that doesn't natively support range
224+
formatting (invoked by {cmd}), using a hacky strategy of sending those lines
225+
to the formatter in isolation.
226+
227+
If invoking this hack, please make sure to file a feature request against
228+
the tool for range formatting and post a URL for that feature request above
229+
code that calls it.
230+
231+
Throws ERROR(ShellError) if the {cmd} system call fails
232+
214233
==============================================================================
215234
MAPPINGS *codefmt-mappings*
216235

0 commit comments

Comments
 (0)