vim-autoformat/plugin/autoformat.vim

166 lines
5.2 KiB
VimL
Raw Normal View History

" Function for finding the formatters for this filetype
" Result is stored in b:formatters
function! s:find_formatters(...)
" Detect verbosity
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")
2015-05-30 15:00:16 -04:00
" Warn for backward incompatible configuration
let old_formatprg_var = "g:formatprg_".type
let old_formatprg_args_var = "g:formatprg_args_".type
let old_formatprg_args_expr_var = "g:formatprg_args_expr_".type
if exists(old_formatprg_var) || exists(old_formatprg_args_var) || exists(old_formatprg_args_expr_var)
echom "WARNING: the options g:formatprg_<filetype>, g:formatprg_args_<filetype> and g:formatprg_args_expr_<filetype> are no longer supported as of June 2015. Please check the README for help on how to configure your formatters."
endif
" Detect configuration
let formatters_var = "g:formatters_".type
let b:formatters = []
if !exists(formatters_var)
" No formatters defined
if verbose
echoerr "No formatters defined for filetype '".type."'."
endif
2013-03-15 18:12:09 -04:00
return 0
2013-03-14 13:50:31 -04:00
endif
let formatters = eval(formatters_var)
if len(formatters) == 0
" No formatters defined
if verbose
echoerr "No formatters defined for filetype '".type."'."
2013-03-14 13:50:31 -04:00
endif
2013-12-20 14:34:38 -05:00
return 0
2013-03-14 13:50:31 -04:00
endif
let b:formatters = formatters
return 1
endfunction
" Try all formatters, starting with the currently selected one, until one
" works. If none works, autoindent the buffer.
2015-05-30 05:02:07 -04:00
function! s:TryAllFormatters(...) range
"echom a:firstline.", ".a:lastline
2015-05-30 05:02:07 -04:00
"echom line('.')", ".line('v')
"echom line("'<")", ".line("'>")
"echom mode()
" Make sure formatters are defined and detected
if !call('<SID>find_formatters', a:000)
return 0
endif
" Make sure index exist and is valid
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
if b:current_formatter_index >= len(b:formatters)
let b:current_formatter_index = 0
endif
" Try all formatters, starting with selected one
let s:index = b:current_formatter_index
while 1
let formatdef_var = 'g:formatdef_'.b:formatters[s:index]
" Formatter definition must be existent
if !exists(formatdef_var)
echoerr "No format definition found in '".formatdef_var."'."
return 0
endif
" Eval twice, once for getting definition content,
" once for getting the final expression
let &formatprg = eval(eval(formatdef_var))
if s:TryFormatter()
return 1
else
let s:index = (s:index + 1) % len(b:formatters)
endif
if s:index == b:current_formatter_index
" Tried all formatters, none worked
return 0
endif
endwhile
" Autoindent code if no formatters work
exe "normal gg=G"
2013-03-15 18:12:09 -04:00
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")
2013-03-14 13:50:31 -04:00
" Save window state
2013-03-15 18:12:09 -04:00
let winview=winsaveview()
python << EOF
import vim, subprocess, os
from subprocess import Popen, PIPE
text = '\n'.join(vim.current.buffer[:])
formatprg = vim.eval('&formatprg')
verbose = bool(int(vim.eval('verbose')))
env = os.environ.copy()
if int(vim.eval('exists("g:formatterpath")')):
extra_path = vim.eval('g:formatterpath')
env['PATH'] = ':'.join(extra_path) + ':' + env['PATH']
p = subprocess.Popen(formatprg, env=env, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdoutdata, stderrdata = p.communicate(text)
if stderrdata:
if verbose:
formattername = vim.eval('b:formatters[s:index]')
2015-05-30 05:02:07 -04:00
print('Formatter {} has errors: {}. Skipping.'.format(formattername, stderrdata))
print('Failing config: {} '.format(repr(formatprg), stderrdata))
vim.command('return 0')
else:
vim.current.buffer[:] = stdoutdata.split('\n')
EOF
" Recall window state
2013-03-15 18:12:09 -04:00
call winrestview(winview)
return 1
2013-03-14 13:50:31 -04:00
endfunction
" Create a command for formatting the entire buffer
2015-05-30 05:02:07 -04:00
command! -nargs=? -range=% -complete=filetype Autoformat <line1>,<line2>call s:TryAllFormatters(<f-args>)
" Functions for iterating through list of available formatters
function! s:NextFormatter()
call s:find_formatters()
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
let b:current_formatter_index = (b:current_formatter_index + 1) % len(b:formatters)
echom 'Selected formatter: '.b:formatters[b:current_formatter_index]
endfunction
function! s:PreviousFormatter()
call s:find_formatters()
if !exists('b:current_formatter_index')
let b:current_formatter_index = 0
endif
let l = len(b:formatters)
let b:current_formatter_index = (b:current_formatter_index - 1 + l) % l
echom 'Selected formatter: '.b:formatters[b:current_formatter_index]
endfunction
" Create commands for iterating through formatter list
command! NextFormatter call s:NextFormatter()
command! PreviousFormatter call s:PreviousFormatter()