Try all available formatters until one works
This commit is contained in:
parent
dfd9461f23
commit
2ed8f00bb5
18
README.md
18
README.md
@ -148,11 +148,19 @@ For the exact default definitions, have a look in `vim-autoformat/plugin/default
|
||||
|
||||
If you have a composite filetype with dots (like `django.python` or `php.wordpress`), vim-autoformat internally replaces the dots with underscores so you can define formatters through `g:formatprg_django_python` and so on.
|
||||
|
||||
Debugging
|
||||
---------
|
||||
If you're struggling with getting a formatter to work, it may help to set vim-autoformat in
|
||||
verbose-mode. Vim-autoformat will then output errors on formatters that failed.
|
||||
```vim
|
||||
let g:autoformat_verbosemode = 1
|
||||
```
|
||||
To read all messages in a vim session type `:messages`.
|
||||
|
||||
Things that are not (yet) implemented
|
||||
----------------------------------------------------------
|
||||
--------------------------------------
|
||||
* Support toggling between multiple formatters, as requested and described in #46.
|
||||
* Make Autoformat command accept ranges and provide range information to formatter if they support that, as requested and described in #47.
|
||||
* Make `:Autoformat` command accept ranges and provide range information to formatter if they support that, as requested and described in #47.
|
||||
* Automatically check for formatters of supertypes, as requested and described in #50.
|
||||
* Option for on-the-fly code-formatting, like visual studio (If ever. When you have a clever idea about how to do this, I'd be glad to hear.)
|
||||
|
||||
@ -162,6 +170,12 @@ If you have any suggestions on this plugin or on this readme, if you have some n
|
||||
|
||||
Change log
|
||||
----------
|
||||
### May 21 2015
|
||||
* Backwards incompatible patch!
|
||||
* Multiple formatters per filetype are now supported
|
||||
* configuration variable names changed
|
||||
* `gq` no longer supported
|
||||
|
||||
### Dec 9 2014
|
||||
* Added `rbeautify` to the defaults for formatting ruby files
|
||||
|
||||
|
@ -1,46 +1,46 @@
|
||||
" TODO:
|
||||
" - Make :Autoformat accept ranges
|
||||
|
||||
|
||||
" Function for finding the formatters for this filetype
|
||||
" Result is stored in b:formatters
|
||||
function! s:find_formatters(...)
|
||||
" Detect verbosity
|
||||
let s:verbose = &verbose || exists("g:autoformat_verbosemode")
|
||||
|
||||
let verbose = &verbose || exists("g:autoformat_verbosemode")
|
||||
|
||||
" Extract filetype to be used
|
||||
let type = a:0 ? a:1 : &filetype
|
||||
" Support composite filetypes by replacing dots with underscores
|
||||
let type = substitute(type, "[.]", "_", "g")
|
||||
|
||||
|
||||
let s:formatters_var = "g:formatters_".type
|
||||
let formatters_var = "g:formatters_".type
|
||||
let b:formatters = []
|
||||
|
||||
if !exists(s:formatters_var)
|
||||
if !exists(formatters_var)
|
||||
" No formatters defined
|
||||
if s:verbose
|
||||
if verbose
|
||||
echoerr "No formatters defined for filetype '".type."'."
|
||||
endif
|
||||
return 0
|
||||
endif
|
||||
|
||||
let s:formatters = eval(s:formatters_var)
|
||||
if len(s:formatters) == 0
|
||||
let formatters = eval(formatters_var)
|
||||
if len(formatters) == 0
|
||||
" No formatters defined
|
||||
if s:verbose
|
||||
if verbose
|
||||
echoerr "No formatters defined for filetype '".type."'."
|
||||
endif
|
||||
return 0
|
||||
endif
|
||||
|
||||
let b:formatters = s:formatters
|
||||
let b:formatters = formatters
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
|
||||
" Function for finding and setting the currently selected formatter
|
||||
function! s:set_formatter(...)
|
||||
" Detect verbosity
|
||||
let s:verbose = &verbose || exists("g:autoformat_verbosemode")
|
||||
|
||||
|
||||
" Try all formatters, starting with the currently selected one, until one
|
||||
" works. If none works, autoindent the buffer.
|
||||
function! s:TryAllFormatters(...)
|
||||
" Make sure formatters are defined and detected
|
||||
if !call('<SID>find_formatters', a:000)
|
||||
return 0
|
||||
@ -54,45 +54,75 @@ function! s:set_formatter(...)
|
||||
let b:current_formatter_index = 0
|
||||
endif
|
||||
|
||||
" Try all formatters, starting with selected one
|
||||
let index = b:current_formatter_index
|
||||
|
||||
while 1
|
||||
let format_def_var = 'g:format_def_'.b:formatters[index]
|
||||
" Formatter definition must be existent
|
||||
if !exists(format_def_var)
|
||||
echoerr "No format definition found in '".s:format_def_var."'."
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Eval twice, once for getting definition content,
|
||||
" once for getting the final expression
|
||||
let &formatprg = eval(eval(format_def_var))
|
||||
if s:TryFormatter()
|
||||
return 1
|
||||
else
|
||||
let index = (index + 1) % len(b:formatters)
|
||||
endif
|
||||
|
||||
" Tried all formatters, none worked
|
||||
if index == b:current_formatter_index
|
||||
return 0
|
||||
endif
|
||||
endwhile
|
||||
|
||||
|
||||
" Autoindent code if no formatters work
|
||||
exe "normal gg=G"
|
||||
|
||||
let &formatprg = eval(s:formatters[b:current_formatter_index])
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
|
||||
" Call formatter
|
||||
" If stderr is empty, apply result, return 1
|
||||
" Otherwise, return 0
|
||||
function! s:TryFormatter()
|
||||
" Detect verbosity
|
||||
let verbose = &verbose || exists("g:autoformat_verbosemode")
|
||||
|
||||
" Function for formatting the entire buffer
|
||||
function! s:Autoformat(...)
|
||||
" Save window state
|
||||
let winview=winsaveview()
|
||||
|
||||
if call('<SID>set_formatter', a:000)
|
||||
" Autoformat code
|
||||
|
||||
python << EOF
|
||||
import vim, subprocess
|
||||
from subprocess import Popen, PIPE
|
||||
text = '\n'.join(vim.current.buffer[:])
|
||||
formatprg = vim.eval('&formatprg')
|
||||
verbose = vim.eval('verbose')
|
||||
p = subprocess.Popen(formatprg, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
stdoutdata, stderrdata = p.communicate(text)
|
||||
if stderrdata:
|
||||
vim.command('echoerr "Error communicating with formatter: {}"'.format(stderrdata))
|
||||
if verbose:
|
||||
vim.command('echom "Formatter {} has errors: {}. Skipping."'.format(formatprg,
|
||||
stderrdata))
|
||||
vim.command('return 0')
|
||||
else:
|
||||
vim.current.buffer[:] = stdoutdata.split('\n')
|
||||
EOF
|
||||
|
||||
else
|
||||
" Autoindent code
|
||||
exe "normal gg=G"
|
||||
endif
|
||||
|
||||
" Recall window state
|
||||
call winrestview(winview)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
|
||||
" Create a command for formatting the entire buffer
|
||||
command! -nargs=? -complete=filetype Autoformat call s:Autoformat(<f-args>)
|
||||
command! -nargs=? -complete=filetype Autoformat call s:TryAllFormatters(<f-args>)
|
||||
|
||||
|
||||
" Functions for iterating through list of available formatters
|
||||
@ -109,8 +139,8 @@ function! s:PreviousFormatter()
|
||||
if !exists('b:current_formatter_index')
|
||||
let b:current_formatter_index = 0
|
||||
endif
|
||||
let s:l = len(b:formatters)
|
||||
let b:current_formatter_index = (b:current_formatter_index - 1 + s:l) % s:l
|
||||
let l = len(b:formatters)
|
||||
let b:current_formatter_index = (b:current_formatter_index - 1 + l) % l
|
||||
endfunction
|
||||
|
||||
" Create commands for iterating through formatter list
|
||||
|
@ -1,9 +1,15 @@
|
||||
if !exists("g:formatters_python") | let g:formatters_python = [] | endif
|
||||
let g:formatters_python += [
|
||||
\ '"autopep8 - ".(&textwidth ? "--max-line-length=".&textwidth : "")',
|
||||
\ '"asdf"',
|
||||
\ '"autopep8 - --indent-size 2 ".(&textwidth ? "--max-line-length=".&textwidth : "")'
|
||||
\ ]
|
||||
let g:format_def_autopep8 = '"autopep8 - ".(&textwidth ? "--max-line-length=".&textwidth : "")'
|
||||
let g:format_def_test = '"asdf"'
|
||||
let g:format_def_another_autopep8 = '"autopep8 - --indent-size 2 ".(&textwidth ? "--max-line-length=".&textwidth : "")'
|
||||
|
||||
if !exists("g:formatters_python")
|
||||
let g:formatters_python = [
|
||||
\ 'test',
|
||||
\ 'another_autopep8',
|
||||
\ 'autopep8',
|
||||
\ ]
|
||||
endif
|
||||
|
||||
|
||||
"if !exists("g:formatters_cs")
|
||||
"let g:formatters_cs = ['"astyle --mode=cs --style=ansi --indent-namespaces -pcH".(&expandtab ? "s".&shiftwidth : "t")']
|
||||
|
Loading…
Reference in New Issue
Block a user