Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
500 changes: 2 additions & 498 deletions autoload/codefmt.vim

Large diffs are not rendered by default.

96 changes: 96 additions & 0 deletions autoload/codefmt/autopep8.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
" 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
" Invalidates the cached autopep8 version detection info.
function! codefmt#autopep8#InvalidateVersion() abort
unlet! s:autopep8_supports_range
endfunction


""
" @private
" Formatter: autopep8
function! codefmt#autopep8#GetFormatter() abort
let l:formatter = {
\ 'name': 'autopep8',
\ 'setup_instructions': 'Install autopep8 ' .
\ '(https://pypi.python.org/pypi/autopep8/).'}

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

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

""
" Reformat the current buffer with autopep8 or the binary named in
" @flag(autopep8_executable), only targeting the range between {startline} and
" {endline}.
" @throws ShellError
function l:formatter.FormatRange(startline, endline) abort
let l:executable = s:plugin.Flag('autopep8_executable')
if !exists('s:autopep8_supports_range')
let l:version_call =
\ maktaba#syscall#Create([l:executable, '--version']).Call()
" In some cases version is written to stderr, in some to stdout
let l:version_output = empty(version_call.stderr) ?
\ version_call.stdout : version_call.stderr
let l:autopep8_version =
\ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.')
if empty(l:autopep8_version)
throw maktaba#error#Failure(
\ 'Unable to parse version from `%s --version`: %s',
\ l:executable, l:version_output)
else
let s:autopep8_supports_range = l:autopep8_version[1] >= 1
endif
endif

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

if s:autopep8_supports_range
let l:cmd = [l:executable, '--range', ''.a:startline, ''.a:endline, '-']
let l:input = join(l:lines, "\n")
else
let l:cmd = [l:executable, '-']
" Hack range formatting by formatting range individually, ignoring context.
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
endif

let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
let l:formatted = split(l:result.stdout, "\n")

if s:autopep8_supports_range
let l:full_formatted = l:formatted
else
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []
let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
endif

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

return l:formatter
endfunction
1 change: 0 additions & 1 deletion autoload/codefmt/buildifier.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@


let s:plugin = maktaba#plugin#Get('codefmt')
let s:registry = s:plugin.GetExtensionRegistry()


""
Expand Down
133 changes: 133 additions & 0 deletions autoload/codefmt/clangformat.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
" 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:ClangFormatHasAtLeastVersion(minimum_version) abort
if !exists('s:clang_format_version')
let l:executable = s:plugin.Flag('clang_format_executable')
let l:version_output =
\ maktaba#syscall#Create([l:executable, '--version']).Call().stdout
let l:version_string = matchstr(l:version_output, '\v\d+(.\d+)+')
let s:clang_format_version = map(split(l:version_string, '\.'), 'v:val + 0')
endif
let l:length = min([len(a:minimum_version), len(s:clang_format_version)])
for i in range(l:length)
if a:minimum_version[i] < s:clang_format_version[i]
return 1
elseif a:minimum_version[i] > s:clang_format_version[i]
return 0
endif
endfor
return len(a:minimum_version) <= len(s:clang_format_version)
endfunction


""
" @private
" Invalidates the cached clang-format version.
function! codefmt#clangformat#InvalidateVersion() abort
unlet! s:clang_format_version
endfunction


""
" @private
" Formatter: clang-format
function! codefmt#clangformat#GetFormatter() abort
let l:formatter = {
\ 'name': 'clang-format',
\ 'setup_instructions': 'Install clang-format from ' .
\ 'http://clang.llvm.org/docs/ClangFormat.html and ' .
\ 'configure the clang_format_executable flag'}

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

function l:formatter.AppliesToBuffer() abort
if &filetype is# 'c' || &filetype is# 'cpp' ||
\ &filetype is# 'proto' || &filetype is# 'javascript' ||
\ &filetype is# 'typescript'
return 1
endif
" Version 3.6 adds support for java
" http://llvm.org/releases/3.6.0/tools/clang/docs/ReleaseNotes.html
return &filetype is# 'java' && s:ClangFormatHasAtLeastVersion([3, 6])
endfunction

""
" Reformat buffer with clang-format, only targeting [ranges] if given.
function l:formatter.FormatRanges(ranges) abort
let l:Style_value = s:plugin.Flag('clang_format_style')
if type(l:Style_value) is# type('')
let l:style = l:Style_value
elseif maktaba#value#IsCallable(l:Style_value)
let l:style = maktaba#function#Call(l:Style_value)
else
throw maktaba#error#WrongType(
\ 'clang_format_style flag must be string or callable. Found %s',
\ string(l:Style_value))
endif
if empty(a:ranges)
return
endif

let l:cmd = [
\ s:plugin.Flag('clang_format_executable'),
\ '-style', l:style]
let l:fname = expand('%:p')
if !empty(l:fname)
let l:cmd += ['-assume-filename', l:fname]
endif

for [l:startline, l:endline] in a:ranges
call maktaba#ensure#IsNumber(l:startline)
call maktaba#ensure#IsNumber(l:endline)
let l:cmd += ['-lines', l:startline . ':' . l:endline]
endfor

" Version 3.4 introduced support for cursor tracking
" http://llvm.org/releases/3.4/tools/clang/docs/ClangFormat.html
let l:supports_cursor = s:ClangFormatHasAtLeastVersion([3, 4])
if l:supports_cursor
" line2byte counts bytes from 1, and col counts from 1, so -2
let l:cursor_pos = line2byte(line('.')) + col('.') - 2
let l:cmd += ['-cursor', string(l:cursor_pos)]
endif

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")

if !l:supports_cursor
call maktaba#buffer#Overwrite(1, line('$'), l:formatted[0:])
else
call maktaba#buffer#Overwrite(1, line('$'), l:formatted[1:])
try
let l:clang_format_output_json = maktaba#json#Parse(l:formatted[0])
let l:new_cursor_pos =
\ maktaba#ensure#IsNumber(l:clang_format_output_json.Cursor) + 1
execute 'goto' l:new_cursor_pos
catch
call maktaba#error#Warn('Unable to parse clang-format cursor pos: %s',
\ v:exception)
endtry
endif
endfunction

return l:formatter
endfunction
89 changes: 89 additions & 0 deletions autoload/codefmt/dartfmt.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
" 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: dartfmt
function! codefmt#dartfmt#GetFormatter() abort
let l:formatter = {
\ 'name': 'dartfmt',
\ 'setup_instructions': 'Install the Dart SDK from ' .
\ 'https://www.dartlang.org/tools/sdk/'}

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

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

""
" Reformat the current buffer with dartfmt or the binary named in
" @flag(dartfmt_executable}, only targetting the range from {startline} to
" {endline}
function l:formatter.FormatRange(startline, endline) abort
" Hack range formatting by formatting range individually, ignoring context.
let l:cmd = [ s:plugin.Flag('dartfmt_executable') ]
" TODO When https://github.com/dart-lang/dart_style/issues/92 is implemented
" use those options.
call maktaba#ensure#IsNumber(a:startline)
call maktaba#ensure#IsNumber(a:endline)
let l:lines = getline(1, line('$'))
let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n")
try
let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call()
let l:formatted = split(l:result.stdout, "\n")
" Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right.
let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : []

let l:full_formatted = l:before + l:formatted + l:lines[a:endline :]
call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted)
catch /ERROR(ShellError):/
" Parse all the errors and stick them in the quickfix list.
let l:errors = []
for l:line in split(v:exception, "\n")
let l:tokens = matchlist(l:line,
\ '\C\v^line (\d+), column (\d+) of stdin: (.*)')
if !empty(l:tokens)
call add(l:errors, {
\ 'filename': @%,
\ 'lnum': l:tokens[1] + a:startline - 1,
\ 'col': l:tokens[2],
\ 'text': l:tokens[3]})
endif
endfor

if empty(l:errors)
" Couldn't parse dartfmt error format; display it all.
call maktaba#error#Shout('Failed to format range; showing all errors: %s', v:exception)
else
let l:errorHeaderLines = split(v:exception, "\n")[1 : 5]
let l:errorHeader = join(l:errorHeaderLines, "\n")
call maktaba#error#Shout(
\ "Error formatting file:\n%s\n\nMore errors in the fixlist.",
\ l:errorHeader)
call setqflist(l:errors, 'r')
cc 1
endif
endtry
endfunction

return l:formatter
endfunction

Loading