Skip to content

Commit

Permalink
Split out all the plugins into separate files for readability.
Browse files Browse the repository at this point in the history
  • Loading branch information
artasparks committed Jan 23, 2017
1 parent b97f44b commit b2277e9
Show file tree
Hide file tree
Showing 10 changed files with 633 additions and 507 deletions.
500 changes: 2 additions & 498 deletions autoload/codefmt.vim

Large diffs are not rendered by default.

97 changes: 97 additions & 0 deletions autoload/codefmt/autopep8.vim
@@ -0,0 +1,97 @@
" 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')
let s:registry = s:plugin.GetExtensionRegistry()


""
" @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
134 changes: 134 additions & 0 deletions autoload/codefmt/clangformat.vim
@@ -0,0 +1,134 @@
" 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')
let s:registry = s:plugin.GetExtensionRegistry()


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
90 changes: 90 additions & 0 deletions autoload/codefmt/dartfmt.vim
@@ -0,0 +1,90 @@
" 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')
let s:registry = s:plugin.GetExtensionRegistry()


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

0 comments on commit b2277e9

Please sign in to comment.