From 67f3e04ee945a597efc56354506e285bdc4923f5 Mon Sep 17 00:00:00 2001 From: actionless Date: Fri, 23 Jan 2015 19:29:26 +0100 Subject: [PATCH 1/9] feat(formatters): add autopep8 --- autoload/codefmt.vim | 60 ++++++++++++++++++++++++++++++++++++++++++++ doc/codefmt.txt | 5 ++++ instant/flags.vim | 4 +++ 3 files changed, 69 insertions(+) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index d1dc179..f92cec0 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -156,7 +156,67 @@ if !exists('s:gofmt') call codefmtlib#AddDefaultFormatter(s:gofmt) endif +" Formatter: autopep8 +if !exists('s:autopep8') + let s:autopep8 = { + \ 'name': 'autopep8', + \ 'setup_instructions': 'Install autopep8 and '} + + function s:autopep8.IsAvailable() abort + return executable(s:plugin.Flag('autopep8_executable')) + endfunction + + function s:autopep8.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}. + function s:autopep8.FormatRange(startline, endline) abort + " Hack range formatting by formatting range individually, ignoring context. + let l:cmd = [ s:plugin.Flag('autopep8_executable'), "-" ] + 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^\:(\d+):(\d+):\s*(.*)') + 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 autopep8 error format; display it all. + call maktaba#error#Shout('Error formatting file: %s', v:exception) + else + call setqflist(l:errors, 'r') + cc 1 + endif + endtry + endfunction + + call codefmtlib#AddDefaultFormatter(s:autopep8) +endif "" " Detects whether a formatter has been defined for the current buffer/filetype. function! codefmt#IsFormatterAvailable() abort diff --git a/doc/codefmt.txt b/doc/codefmt.txt index eceb89f..5c1b895 100644 --- a/doc/codefmt.txt +++ b/doc/codefmt.txt @@ -23,6 +23,10 @@ This plugin uses maktaba flags for configuration. Install Glaive (https://github.com/google/glaive) and use the |:Glaive| command to configure them. + *codefmt:autopep8_executable* +The path to the autopep8 executable. +Default: 'autopep8' ` + *codefmt:clang_format_executable* The path to the clang-format executable. Default: 'clang-format' ` @@ -75,6 +79,7 @@ plugins are enabled or what other software is installed on your system. The current list of defaults by filetype is: * cpp, proto, javascript: clang-format * go: gofmt + * python: autopep8 ============================================================================== COMMANDS *codefmt-commands* diff --git a/instant/flags.vim b/instant/flags.vim index e1fb46e..82c8532 100644 --- a/instant/flags.vim +++ b/instant/flags.vim @@ -32,6 +32,10 @@ if !s:enter endif +"" +" The path to the autopep8 executable. +call s:plugin.Flag('autopep8_executable', 'autopep8') + "" " The path to the clang-format executable. call s:plugin.Flag('clang_format_executable', 'clang-format') From 85472f9bc2374e24257b788de32abcdffeac0d29 Mon Sep 17 00:00:00 2001 From: actionless Date: Sun, 25 Jan 2015 13:03:29 +0100 Subject: [PATCH 2/9] chore(docs): add short formatter description; regenerate docs with vimdoc --- autoload/codefmt.vim | 1 + doc/codefmt.txt | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index f92cec0..26d6a73 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -27,6 +27,7 @@ " The current list of defaults by filetype is: " * cpp, proto, javascript: clang-format " * go: gofmt +" * python: autopep8 call maktaba#library#Require('codefmtlib') diff --git a/doc/codefmt.txt b/doc/codefmt.txt index 5c1b895..090698f 100644 --- a/doc/codefmt.txt +++ b/doc/codefmt.txt @@ -1,5 +1,5 @@ -*codefmt.txt* Syntax-aware code formatting - *codefmt* +*codefmt.txt* Syntax-aware code formatting for a variety of languages +Google *codefmt* ============================================================================== CONTENTS *codefmt-contents* @@ -23,7 +23,7 @@ This plugin uses maktaba flags for configuration. Install Glaive (https://github.com/google/glaive) and use the |:Glaive| command to configure them. - *codefmt:autopep8_executable* + *codefmt:autopep8_executable* The path to the autopep8 executable. Default: 'autopep8' ` @@ -38,9 +38,9 @@ http://clang.llvm.org/docs/ClangFormatStyleOptions.html for details. Default: 'file' ` *codefmt:gofmt_executable* -The path to the gofmt executable. For example, this can be changed to -"goimports" (http://go/goimports) to additionally adjust imports when -formatting. +The path to the gofmt executable. For example, this can be changed to +"goimports" (https://godoc.org/golang.org/x/tools/cmd/goimports) to +additionally adjust imports when formatting. Default: 'gofmt' ` *codefmt:plugin[autocmds]* From 26c1d9baed2668d471e315cc0d80ac02f402f185 Mon Sep 17 00:00:00 2001 From: actionless Date: Sun, 25 Jan 2015 13:06:09 +0100 Subject: [PATCH 3/9] fix(formatters: autopep8): correct setup_instructions --- autoload/codefmt.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index 26d6a73..e07d7bc 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -161,7 +161,8 @@ endif if !exists('s:autopep8') let s:autopep8 = { \ 'name': 'autopep8', - \ 'setup_instructions': 'Install autopep8 and '} + \ 'setup_instructions': 'Install autopep8 ' . + \ '(https://pypi.python.org/pypi/autopep8/).'} function s:autopep8.IsAvailable() abort return executable(s:plugin.Flag('autopep8_executable')) From 8045f9cb177a3684678fbbb98bd9943424052436 Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 15:34:55 +0100 Subject: [PATCH 4/9] fix(formatters: autopep8): remove redundant try/catch --- autoload/codefmt.vim | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index e07d7bc..bf86ef4 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -162,7 +162,7 @@ if !exists('s:autopep8') let s:autopep8 = { \ 'name': 'autopep8', \ 'setup_instructions': 'Install autopep8 ' . - \ '(https://pypi.python.org/pypi/autopep8/).'} + \ '(https://pypi.python.org/pypi/autopep8/).'} function s:autopep8.IsAvailable() abort return executable(s:plugin.Flag('autopep8_executable')) @@ -172,11 +172,11 @@ if !exists('s:autopep8') 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 s:autopep8.FormatRange(startline, endline) abort " Hack range formatting by formatting range individually, ignoring context. let l:cmd = [ s:plugin.Flag('autopep8_executable'), "-" ] @@ -184,41 +184,19 @@ if !exists('s:autopep8') 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^\:(\d+):(\d+):\s*(.*)') - 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 + 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] : [] - if empty(l:errors) - " Couldn't parse autopep8 error format; display it all. - call maktaba#error#Shout('Error formatting file: %s', v:exception) - else - call setqflist(l:errors, 'r') - cc 1 - endif - endtry + let l:full_formatted = l:before + l:formatted + l:lines[a:endline :] + call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted) endfunction call codefmtlib#AddDefaultFormatter(s:autopep8) endif + "" " Detects whether a formatter has been defined for the current buffer/filetype. function! codefmt#IsFormatterAvailable() abort From 8424eb7c5cadde924bf6db9071cb5d0633edaf05 Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 16:22:04 +0100 Subject: [PATCH 5/9] feat(formatters: autopep8): use --range if supported --- autoload/codefmt.vim | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index bf86ef4..90479cf 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -179,18 +179,38 @@ if !exists('s:autopep8') " @throws ShellError function s:autopep8.FormatRange(startline, endline) abort " Hack range formatting by formatting range individually, ignoring context. - let l:cmd = [ s:plugin.Flag('autopep8_executable'), "-" ] + let l:executable = s:plugin.Flag('autopep8_executable') + if !exists('s:autopep8_supports_range') + let l:version_output = + \ maktaba#syscall#Create([l:executable, '--version']).Call().stderr + let s:autopep8_supports_range = + \ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.')[1] >= 1 + endif + 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") + + 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, '-' ] + 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") - " 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 :] + 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 From fe1631869c25ead9b79377ec76b0d3f029dcd68b Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 19:14:00 +0100 Subject: [PATCH 6/9] fix(formatters: autopep8): version can be in either stdout and stderr on some setups --- autoload/codefmt.vim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index 90479cf..5ea1093 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -181,8 +181,10 @@ if !exists('s:autopep8') " Hack range formatting by formatting range individually, ignoring context. let l:executable = s:plugin.Flag('autopep8_executable') if !exists('s:autopep8_supports_range') + let l:version_call = + \ maktaba#syscall#Create([l:executable, '--version', '1>&2']).Call() let l:version_output = - \ maktaba#syscall#Create([l:executable, '--version']).Call().stderr + \version_call.stderr ? version_call.stderr : version_call.stdout let s:autopep8_supports_range = \ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.')[1] >= 1 endif From c102e13c1a6ed06d49e686b58008f621544d90d3 Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 19:14:39 +0100 Subject: [PATCH 7/9] style(formatters: autopep8): make command more readable --- autoload/codefmt.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index 5ea1093..207a478 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -194,8 +194,9 @@ if !exists('s:autopep8') let l:lines = getline(1, line('$')) if s:autopep8_supports_range - let l:cmd = [ l:executable, '-', '--range', - \ ''.a:startline, ''.a:endline ] + let l:cmd = [ l:executable, + \ '--range', ''.a:startline, ''.a:endline, + \ '-' ] let l:input = join(l:lines, "\n") else let l:cmd = [ l:executable, '-' ] From 95b5adff4770b3b14cb896c0d560ddf92c42461b Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 19:17:12 +0100 Subject: [PATCH 8/9] fix(formatters: autopep8): remove debug code --- autoload/codefmt.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index 207a478..b5f0fc9 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -182,7 +182,7 @@ if !exists('s:autopep8') let l:executable = s:plugin.Flag('autopep8_executable') if !exists('s:autopep8_supports_range') let l:version_call = - \ maktaba#syscall#Create([l:executable, '--version', '1>&2']).Call() + \ maktaba#syscall#Create([l:executable, '--version']).Call() let l:version_output = \version_call.stderr ? version_call.stderr : version_call.stdout let s:autopep8_supports_range = From 35e4860115ed2156091cc8a76cdc169d985d78d3 Mon Sep 17 00:00:00 2001 From: actionless Date: Mon, 26 Jan 2015 22:28:43 +0100 Subject: [PATCH 9/9] style(formatters: autopep8): updated comments; add missing space --- autoload/codefmt.vim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/autoload/codefmt.vim b/autoload/codefmt.vim index b5f0fc9..5df140d 100644 --- a/autoload/codefmt.vim +++ b/autoload/codefmt.vim @@ -178,13 +178,13 @@ if !exists('s:autopep8') " {endline}. " @throws ShellError function s:autopep8.FormatRange(startline, endline) abort - " Hack range formatting by formatting range individually, ignoring context. 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 = - \version_call.stderr ? version_call.stderr : version_call.stdout + \ version_call.stderr ? version_call.stderr : version_call.stdout let s:autopep8_supports_range = \ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.')[1] >= 1 endif @@ -200,6 +200,7 @@ if !exists('s:autopep8') 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