|  | 
| 27 | 27 | " The current list of defaults by filetype is: | 
| 28 | 28 | " * cpp, proto, javascript: clang-format | 
| 29 | 29 | " * go: gofmt | 
|  | 30 | +" * python: autopep8 | 
| 30 | 31 | 
 | 
| 31 | 32 | 
 | 
| 32 | 33 | call maktaba#library#Require('codefmtlib') | 
| @@ -156,6 +157,69 @@ if !exists('s:gofmt') | 
| 156 | 157 |  call codefmtlib#AddDefaultFormatter(s:gofmt) | 
| 157 | 158 | endif | 
| 158 | 159 | 
 | 
|  | 160 | +" Formatter: autopep8 | 
|  | 161 | +if !exists('s:autopep8') | 
|  | 162 | + let s:autopep8 = { | 
|  | 163 | + \ 'name': 'autopep8', | 
|  | 164 | + \ 'setup_instructions': 'Install autopep8 ' . | 
|  | 165 | + \ '(https://pypi.python.org/pypi/autopep8/).'} | 
|  | 166 | + | 
|  | 167 | + function s:autopep8.IsAvailable() abort | 
|  | 168 | + return executable(s:plugin.Flag('autopep8_executable')) | 
|  | 169 | + endfunction | 
|  | 170 | + | 
|  | 171 | + function s:autopep8.AppliesToBuffer() abort | 
|  | 172 | + return &filetype is# 'python' | 
|  | 173 | + endfunction | 
|  | 174 | + | 
|  | 175 | + "" | 
|  | 176 | + " Reformat the current buffer with autopep8 or the binary named in | 
|  | 177 | + " @flag(autopep8_executable), only targeting the range between {startline} and | 
|  | 178 | + " {endline}. | 
|  | 179 | + " @throws ShellError | 
|  | 180 | + function s:autopep8.FormatRange(startline, endline) abort | 
|  | 181 | + let l:executable = s:plugin.Flag('autopep8_executable') | 
|  | 182 | + if !exists('s:autopep8_supports_range') | 
|  | 183 | + let l:version_call = | 
|  | 184 | + \ maktaba#syscall#Create([l:executable, '--version']).Call() | 
|  | 185 | + " In some cases version is written to stderr, in some to stdout | 
|  | 186 | + let l:version_output = | 
|  | 187 | + \ version_call.stderr ? version_call.stderr : version_call.stdout | 
|  | 188 | + let s:autopep8_supports_range = | 
|  | 189 | + \ matchlist(l:version_output, '\m\Cautopep8 \(\d\+\)\.')[1] >= 1 | 
|  | 190 | + endif | 
|  | 191 | + | 
|  | 192 | + call maktaba#ensure#IsNumber(a:startline) | 
|  | 193 | + call maktaba#ensure#IsNumber(a:endline) | 
|  | 194 | + let l:lines = getline(1, line('$')) | 
|  | 195 | + | 
|  | 196 | + if s:autopep8_supports_range | 
|  | 197 | + let l:cmd = [ l:executable, | 
|  | 198 | + \ '--range', ''.a:startline, ''.a:endline, | 
|  | 199 | + \ '-' ] | 
|  | 200 | + let l:input = join(l:lines, "\n") | 
|  | 201 | + else | 
|  | 202 | + let l:cmd = [ l:executable, '-' ] | 
|  | 203 | + " Hack range formatting by formatting range individually, ignoring context. | 
|  | 204 | + let l:input = join(l:lines[a:startline - 1 : a:endline - 1], "\n") | 
|  | 205 | + endif | 
|  | 206 | + | 
|  | 207 | + let l:result = maktaba#syscall#Create(l:cmd).WithStdin(l:input).Call() | 
|  | 208 | + let l:formatted = split(l:result.stdout, "\n") | 
|  | 209 | + | 
|  | 210 | + if s:autopep8_supports_range | 
|  | 211 | + let l:full_formatted = l:formatted | 
|  | 212 | + else | 
|  | 213 | + " Special case empty slice: neither l:lines[:0] nor l:lines[:-1] is right. | 
|  | 214 | + let l:before = a:startline > 1 ? l:lines[ : a:startline - 2] : [] | 
|  | 215 | + let l:full_formatted = l:before + l:formatted + l:lines[a:endline :] | 
|  | 216 | + endif | 
|  | 217 | + | 
|  | 218 | + call maktaba#buffer#Overwrite(1, line('$'), l:full_formatted) | 
|  | 219 | + endfunction | 
|  | 220 | + | 
|  | 221 | + call codefmtlib#AddDefaultFormatter(s:autopep8) | 
|  | 222 | +endif | 
| 159 | 223 | 
 | 
| 160 | 224 | "" | 
| 161 | 225 | " Checks whether {formatter} is available. | 
|  | 
0 commit comments