From f256d815e7ec7d1f1b728666983aad7c29d660de Mon Sep 17 00:00:00 2001 From: Chiel92 Date: Sun, 31 May 2015 21:56:00 +0200 Subject: [PATCH] Automatically check for supertype formatters, as requested in #50 --- README.md | 13 ++++------- plugin/autoformat.vim | 53 +++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 05acabf..3f6165d 100644 --- a/README.md +++ b/README.md @@ -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?* 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. -#TODO -* 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: +* 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: ```vim 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`. 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. To use this, provide a range to the `:Autoformat` command, for instance by visually selecting a 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. *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 `` are defined in `g:formatters_`. This is a list containing string indentifiers, which point to corresponding formatter 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. -#### Ranged Definitions +#### Ranged definitions If your format program supports formatting specific ranges, you can provide a format 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 @@ -175,10 +176,6 @@ let g:autoformat_verbosemode = 1 ``` 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 ------------ Pull requests are welcome. diff --git a/plugin/autoformat.vim b/plugin/autoformat.vim index cee266d..00f148b 100644 --- a/plugin/autoformat.vim +++ b/plugin/autoformat.vim @@ -5,40 +5,46 @@ function! s:find_formatters(...) let verbose = &verbose || exists("g:autoformat_verbosemode") " 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 - 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 - 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 + let old_formatprg_var = "g:formatprg_".compoundtype + let old_formatprg_args_var = "g:formatprg_args_".compoundtype + 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) echom "WARNING: the options g:formatprg_, g:formatprg_args_ and g:formatprg_args_expr_ 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 + " Detect configuration for all possible supertypes 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 if verbose - echoerr "No formatters defined for filetype '".type."'." + echoerr "No formatters defined for filetype '".ftype."'." endif return 0 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 endfunction @@ -46,11 +52,6 @@ endfunction " Try all formatters, starting with the currently selected one, until one " works. If none works, autoindent the buffer. 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 if !call('find_formatters', a:000) return 0 @@ -110,6 +111,7 @@ function! s:TryFormatter() 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'))) @@ -117,6 +119,7 @@ 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: