diff --git a/autoload/neoformat.vim b/autoload/neoformat.vim index 1e8fae9a..29e922cd 100644 --- a/autoload/neoformat.vim +++ b/autoload/neoformat.vim @@ -75,20 +75,42 @@ function! s:neoformat(bang, user_input, start_line, end_line) abort continue endif - let stdin = getbufline(bufnr('%'), a:start_line, a:end_line) + if cmd.range + " Pass the entire buffer, the formatter itself takes a range. + let stdin = getbufline(bufnr('%'), 1, '$') + else + let lines_after = getbufline(bufnr('%'), a:end_line + 1, '$') + let lines_before = getbufline(bufnr('%'), 1, a:start_line - 1) + let stdin = getbufline(bufnr('%'), a:start_line, a:end_line) + end + let original_buffer = getbufline(bufnr('%'), 1, '$') + let exe = cmd.exe + let replacements = { + \ 'start_byte': line2byte(a:start_line), + \ 'end_byte': line2byte(a:end_line), + \ 'bytes': line2byte(a:end_line) - line2byte(a:start_line), + \ 'start_line': a:start_line, + \ 'end_line': a:end_line, + \ 'lines': a:end_line - a:start_line, + \ } + + for [key, value] in items(replacements) + let exe = substitute(exe, '<'.key.'>', value, 'g') + endfor + call neoformat#utils#log(stdin) - call neoformat#utils#log(cmd.exe) + call neoformat#utils#log(exe) if cmd.stdin call neoformat#utils#log('using stdin') let stdin_str = join(stdin, "\n") - let stdout = split(system(cmd.exe, stdin_str), '\n') + let stdout = split(system(exe, stdin_str), '\n') else call neoformat#utils#log('using tmp file') call writefile(stdin, cmd.tmp_file_path) - let stdout = split(system(cmd.exe), '\n') + let stdout = split(system(exe), '\n') endif " read from /tmp file if formatter replaces file on format @@ -108,11 +130,15 @@ function! s:neoformat(bang, user_input, start_line, end_line) abort call neoformat#utils#log_file_content(cmd.stderr_log) endif if process_ran_succesfully - " 1. append the lines that are before and after the formatterd content - let lines_after = getbufline(bufnr('%'), a:end_line + 1, '$') - let lines_before = getbufline(bufnr('%'), 1, a:start_line - 1) + if cmd.range + let new_buffer = stdout + else + " 1. append the lines that are before and after the formatterd content + let lines_after = getbufline(bufnr('%'), a:end_line + 1, '$') + let lines_before = getbufline(bufnr('%'), 1, a:start_line - 1) + let new_buffer = lines_before + stdout + lines_after + endif - let new_buffer = lines_before + stdout + lines_after if new_buffer !=# original_buffer call s:deletelines(len(new_buffer), line('$')) @@ -274,6 +300,7 @@ function! s:generate_cmd(definition, filetype) abort \ 'name': a:definition.exe, \ 'replace': get(a:definition, 'replace', 0), \ 'tmp_file_path': path, + \ 'range': get(a:definition, 'range', 0), \ 'valid_exit_codes': get(a:definition, 'valid_exit_codes', [0]), \ } endfunction diff --git a/autoload/neoformat/formatters/javascript.vim b/autoload/neoformat/formatters/javascript.vim index 98362f2c..b2ccbb00 100644 --- a/autoload/neoformat/formatters/javascript.vim +++ b/autoload/neoformat/formatters/javascript.vim @@ -39,8 +39,15 @@ endfunction function! neoformat#formatters#javascript#prettier() abort return { \ 'exe': 'prettier', - \ 'args': ['--stdin', '--stdin-filepath', '%:p'], + \ 'args': ['--stdin', + \ '--stdin-filepath', + \ '%:p', + \ '--range-start', + \ '', + \ '--range-end', + \ ''], \ 'stdin': 1, + \ 'range': 1, \ } endfunction diff --git a/autoload/neoformat/formatters/python.vim b/autoload/neoformat/formatters/python.vim index ec56cf6c..4d12f0a8 100644 --- a/autoload/neoformat/formatters/python.vim +++ b/autoload/neoformat/formatters/python.vim @@ -5,7 +5,9 @@ endfunction function! neoformat#formatters#python#yapf() abort return { \ 'exe': 'yapf', + \ 'args': ['--lines', '-'], \ 'stdin': 1, + \ 'range': 1, \ } endfunction diff --git a/doc/neoformat.txt b/doc/neoformat.txt index c9158b99..e46a3ea3 100644 --- a/doc/neoformat.txt +++ b/doc/neoformat.txt @@ -6,6 +6,7 @@ Introduction |neoformat-introduction| Install |neoformat-install| Usage |neoformat-usage| Managing Undo History |neoformat-managing-undo-history| +Argument Templates neoformat-argument-templates Supported Filetypes |neoformat-supported-filetypes| ============================================================================== @@ -92,6 +93,9 @@ Options: | `stderr` | used to specify whether stderr output should be read along with the stdin, otherwise redirects stderr to `stderr.log` file in neoformat's temporary directory | default 0 | optional +| `range` | formatter takes range as argument when using visual formatting. when set to 1, the entire buffer + will be passed in, the range shoudl be passed as an argument to the formatter | + default: 0 | optional | `no_append` | do not append the `path` of the file to the formatter command, used when the `path` is in the middle of a command | default: 0 | optional @@ -202,6 +206,35 @@ When |undojoin| is used this way pressing |u| will "skip over" the Neoformat changes - it will revert both the changes made by Neoformat and the change that caused Neoformat to be invoked. +============================================================================== +ARGUMENT TEMPLATES *neoformat-argument-templates* + +The following strings will be expanded in the 'args' field: + + - - starting line of range + - - ending line of range + - - number of lines in range + - - starting byte of range (from line2byte) + - - ending byte of range (from line2byte) + - - number of bytes in range + - any expressions supported by |expand()| + +Example: + + let g:neoformat_cpp_clangformat = { + \ 'exe': 'clang-format', + \ 'args': ['-lines=:'], + \ 'range': 1, + \ 'stdin', 1, + \ } + + let g:neoformat_cpp_clangformat = { + \ 'exe': 'clang-format', + \ 'args': ['-offset=', '-length='], + \ 'range': 1, + \ 'stdin', 1, + \ } + ============================================================================== SUPPORTED FILETYPES *neoformat-supported-filetypes*