Automatically check for supertype formatters, as requested in #50

This commit is contained in:
Chiel92 2015-05-31 21:56:00 +02:00
parent b553cd17de
commit f256d815e7
2 changed files with 33 additions and 33 deletions

View File

@ -34,8 +34,7 @@ This can either be one of the programs that are listed below as defaultprograms,
For using a custom formatprogram, read the text below *How can I change the behaviour of formatters, or add one myself?* For using a custom formatprogram, read the text below *How can I change the behaviour of formatters, or add one myself?*
If the formatprogram you want to use is installed in one of the following ways, vim automatically detects it: If the formatprogram you want to use is installed in one of the following ways, vim automatically detects it:
* It suffices to make the formatprogram globally available, which is the case if you install it via your package manager. * It suffices to make the formatprogram globally available, which is the case if you install it via your package manager.
#TODO * Alternatively you can point vim-autoformat to folders containing formatters, by putting the absolute paths to these folders in `g:formatterpath` in your .vimrc, like:
* Alternatively you can point vim-autoformat to folders containing formatters, by putting the absolute paths to these folders in `g:formatpath` in your .vimrc, like:
```vim ```vim
let g:formatterpath = ['/some/path/to/a/folder', '/home/superman/formatters'] let g:formatterpath = ['/some/path/to/a/folder', '/home/superman/formatters']
``` ```
@ -45,6 +44,8 @@ This will fix at least the indentation of your code, according to vim's indentfi
When you have installed the formatter you need, you can format the entire buffer with the command `:Autoformat`. When you have installed the formatter you need, you can format the entire buffer with the command `:Autoformat`.
You can provide the command with a file type such as `:Autoformat json`, otherwise the buffer's filetype will be used. You can provide the command with a file type such as `:Autoformat json`, otherwise the buffer's filetype will be used.
If you have a composite filetype with dots (like `django.python` or `php.wordpress`), vim-autoformat first tries to detect and use formatters for the exact original filetype, and then tries the same for all supertypes occuring from left to right in the original filetype separated by dots (`.`).
Some formatter support formatting only a part of the file. Some formatter support formatting only a part of the file.
To use this, provide a range to the `:Autoformat` command, for instance by visually selecting a To use this, provide a range to the `:Autoformat` command, for instance by visually selecting a
part of your file, and then executing `:Autoformat`. part of your file, and then executing `:Autoformat`.
@ -120,7 +121,7 @@ How can I change the behaviour of formatters, or add one myself?
If you need a formatter that is not among the defaults, or if you are not satisfied with the default formatting behaviour that is provided by vim-autoformat, you can define it yourself. If you need a formatter that is not among the defaults, or if you are not satisfied with the default formatting behaviour that is provided by vim-autoformat, you can define it yourself.
*The formatprogram must read the unformatted code from the standard input, and write the formatted code to the standard output.* *The formatprogram must read the unformatted code from the standard input, and write the formatted code to the standard output.*
#### Basic Definitions #### Basic definitions
The formatprograms that available for a certain `<filetype>` are defined in `g:formatters_<filetype>`. The formatprograms that available for a certain `<filetype>` are defined in `g:formatters_<filetype>`.
This is a list containing string indentifiers, which point to corresponding formatter This is a list containing string indentifiers, which point to corresponding formatter
definitions. definitions.
@ -152,7 +153,7 @@ 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 specify formatters through `g:formatters_django_python` and so on. 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 specify formatters through `g:formatters_django_python` and so on.
#### Ranged Definitions #### Ranged definitions
If your format program supports formatting specific ranges, you can provide a format If your format program supports formatting specific ranges, you can provide a format
definition which allows to make use of this. definition which allows to make use of this.
The first and last line of the current range can be retrieved by the variables `a:firstline` and The first and last line of the current range can be retrieved by the variables `a:firstline` and
@ -175,10 +176,6 @@ let g:autoformat_verbosemode = 1
``` ```
To read all messages in a vim session type `:messages`. To read all messages in a vim session type `:messages`.
Things that are not (yet) implemented
--------------------------------------
* Automatically check for formatters of supertypes, as requested and described in #50.
Contributing Contributing
------------ ------------
Pull requests are welcome. Pull requests are welcome.

View File

@ -5,40 +5,46 @@ function! s:find_formatters(...)
let verbose = &verbose || exists("g:autoformat_verbosemode") let verbose = &verbose || exists("g:autoformat_verbosemode")
" Extract filetype to be used " Extract filetype to be used
let type = a:0 ? a:1 : &filetype let ftype = a:0 ? a:1 : &filetype
" Support composite filetypes by replacing dots with underscores " Support composite filetypes by replacing dots with underscores
let type = substitute(type, "[.]", "_", "g") let compoundtype = substitute(ftype, "[.]", "_", "g")
" Try all super filetypes in search for formatters in a sane order
let supertypes = [compoundtype] + split(ftype, "[.]")
" Warn for backward incompatible configuration " Warn for backward incompatible configuration
let old_formatprg_var = "g:formatprg_".type let old_formatprg_var = "g:formatprg_".compoundtype
let old_formatprg_args_var = "g:formatprg_args_".type let old_formatprg_args_var = "g:formatprg_args_".compoundtype
let old_formatprg_args_expr_var = "g:formatprg_args_expr_".type let old_formatprg_args_expr_var = "g:formatprg_args_expr_".compoundtype
if exists(old_formatprg_var) || exists(old_formatprg_args_var) || exists(old_formatprg_args_expr_var) 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." 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 endif
" Detect configuration " Detect configuration for all possible supertypes
let formatters_var = "g:formatters_".type
let b:formatters = [] let b:formatters = []
for supertype in supertypes
let formatters_var = "g:formatters_".supertype
if !exists(formatters_var)
" No formatters defined
if verbose
echoerr "No formatters defined for supertype '".supertype
endif
else
let formatters = eval(formatters_var)
if type(formatters) != 3
echoerr formatter_var." is not a list"
else
let b:formatters = b:formatters + formatters
endif
endif
endfor
if !exists(formatters_var) if len(b:formatters) == 0
" No formatters defined " No formatters defined
if verbose if verbose
echoerr "No formatters defined for filetype '".type."'." echoerr "No formatters defined for filetype '".ftype."'."
endif endif
return 0 return 0
endif endif
let formatters = eval(formatters_var)
if len(formatters) == 0
" No formatters defined
if verbose
echoerr "No formatters defined for filetype '".type."'."
endif
return 0
endif
let b:formatters = formatters
return 1 return 1
endfunction endfunction
@ -46,11 +52,6 @@ endfunction
" Try all formatters, starting with the currently selected one, until one " Try all formatters, starting with the currently selected one, until one
" works. If none works, autoindent the buffer. " works. If none works, autoindent the buffer.
function! s:TryAllFormatters(...) range function! s:TryAllFormatters(...) range
"echom a:firstline.", ".a:lastline
"echom line('.')", ".line('v')
"echom line("'<")", ".line("'>")
"echom mode()
" Make sure formatters are defined and detected " Make sure formatters are defined and detected
if !call('<SID>find_formatters', a:000) if !call('<SID>find_formatters', a:000)
return 0 return 0
@ -110,6 +111,7 @@ function! s:TryFormatter()
python << EOF python << EOF
import vim, subprocess, os import vim, subprocess, os
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
text = '\n'.join(vim.current.buffer[:]) text = '\n'.join(vim.current.buffer[:])
formatprg = vim.eval('&formatprg') formatprg = vim.eval('&formatprg')
verbose = bool(int(vim.eval('verbose'))) verbose = bool(int(vim.eval('verbose')))
@ -117,6 +119,7 @@ env = os.environ.copy()
if int(vim.eval('exists("g:formatterpath")')): if int(vim.eval('exists("g:formatterpath")')):
extra_path = vim.eval('g:formatterpath') extra_path = vim.eval('g:formatterpath')
env['PATH'] = ':'.join(extra_path) + ':' + env['PATH'] env['PATH'] = ':'.join(extra_path) + ':' + env['PATH']
p = subprocess.Popen(formatprg, env=env, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) p = subprocess.Popen(formatprg, env=env, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdoutdata, stderrdata = p.communicate(text) stdoutdata, stderrdata = p.communicate(text)
if stderrdata: if stderrdata: