Refactor special command parsing into its own file

This commit is contained in:
w0rp 2017-05-17 11:17:49 +01:00
parent 164c4efb32
commit f7fc54262d
3 changed files with 74 additions and 60 deletions

57
autoload/ale/command.vim Normal file
View File

@ -0,0 +1,57 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: Special command formatting for creating temporary files and
" passing buffer filenames easily.
function! s:TemporaryFilename(buffer) abort
let l:filename = fnamemodify(bufname(a:buffer), ':t')
if empty(l:filename)
" If the buffer's filename is empty, create a dummy filename.
let l:ft = getbufvar(a:buffer, '&filetype')
let l:filename = 'file' . ale#filetypes#GuessExtension(l:ft)
endif
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
return tempname() . (has('win32') ? '\' : '/') . l:filename
endfunction
" Given a command string, replace every...
" %s -> with the current filename
" %t -> with the name of an unused file in a temporary directory
" %% -> with a literal %
function! ale#command#FormatCommand(buffer, command, pipe_file_if_needed) abort
let l:temporary_file = ''
let l:command = a:command
" First replace all uses of %%, used for literal percent characters,
" with an ugly string.
let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
" Replace all %s occurences in the string with the name of the current
" file.
if l:command =~# '%s'
let l:filename = fnamemodify(bufname(a:buffer), ':p')
let l:command = substitute(l:command, '%s', '\=ale#Escape(l:filename)', 'g')
endif
if l:command =~# '%t'
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = substitute(l:command, '%t', '\=ale#Escape(l:temporary_file)', 'g')
endif
" Finish formatting so %% becomes %.
let l:command = substitute(l:command, '<<PERCENTS>>', '%', 'g')
if a:pipe_file_if_needed && empty(l:temporary_file)
" If we are to send the Vim buffer to a command, we'll do it
" in the shell. We'll write out the file to a temporary file,
" and then read it back in, in the shell.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
endif
return [l:temporary_file, l:command]
endfunction

View File

@ -313,52 +313,6 @@ function! ale#engine#EscapeCommandPart(command_part) abort
return substitute(a:command_part, '%', '%%', 'g')
endfunction
function! s:TemporaryFilename(buffer) abort
let l:filename = fnamemodify(bufname(a:buffer), ':t')
if empty(l:filename)
" If the buffer's filename is empty, create a dummy filename.
let l:ft = getbufvar(a:buffer, '&filetype')
let l:filename = 'file' . ale#filetypes#GuessExtension(l:ft)
endif
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
return tempname() . (has('win32') ? '\' : '/') . l:filename
endfunction
" Given a command string, replace every...
" %s -> with the current filename
" %t -> with the name of an unused file in a temporary directory
" %% -> with a literal %
function! ale#engine#FormatCommand(buffer, command) abort
let l:temporary_file = ''
let l:command = a:command
" First replace all uses of %%, used for literal percent characters,
" with an ugly string.
let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
" Replace all %s occurences in the string with the name of the current
" file.
if l:command =~# '%s'
let l:filename = fnamemodify(bufname(a:buffer), ':p')
let l:command = substitute(l:command, '%s', '\=ale#Escape(l:filename)', 'g')
endif
if l:command =~# '%t'
" Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function.
let l:temporary_file = s:TemporaryFilename(a:buffer)
let l:command = substitute(l:command, '%t', '\=ale#Escape(l:temporary_file)', 'g')
endif
" Finish formatting so %% becomes %.
let l:command = substitute(l:command, '<<PERCENTS>>', '%', 'g')
return [l:temporary_file, l:command]
endfunction
function! s:CreateTemporaryFileForJob(buffer, temporary_file) abort
if empty(a:temporary_file)
" There is no file, so we didn't create anything.
@ -385,15 +339,7 @@ function! s:RunJob(options) abort
let l:next_chain_index = a:options.next_chain_index
let l:read_buffer = a:options.read_buffer
let [l:temporary_file, l:command] = ale#engine#FormatCommand(l:buffer, l:command)
if l:read_buffer && empty(l:temporary_file)
" If we are to send the Vim buffer to a command, we'll do it
" in the shell. We'll write out the file to a temporary file,
" and then read it back in, in the shell.
let l:temporary_file = s:TemporaryFilename(l:buffer)
let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
endif
let [l:temporary_file, l:command] = ale#command#FormatCommand(l:buffer, l:command, l:read_buffer)
if s:CreateTemporaryFileForJob(l:buffer, l:temporary_file)
" If a temporary filename has been formatted in to the command, then

View File

@ -7,16 +7,16 @@ After:
unlet! g:match
Execute(FormatCommand should do nothing to basic command strings):
AssertEqual ['', 'awesome-linter do something'], ale#engine#FormatCommand(bufnr('%'), 'awesome-linter do something')
AssertEqual ['', 'awesome-linter do something'], ale#command#FormatCommand(bufnr('%'), 'awesome-linter do something', 0)
Execute(FormatCommand should handle %%, and ignore other percents):
AssertEqual ['', '% %%d %%f %x %'], ale#engine#FormatCommand(bufnr('%'), '%% %%%d %%%f %x %')
AssertEqual ['', '% %%d %%f %x %'], ale#command#FormatCommand(bufnr('%'), '%% %%%d %%%f %x %', 0)
Execute(FormatCommand should convert %s to the current filename):
AssertEqual ['', 'foo ' . shellescape(expand('%:p')) . ' bar ' . shellescape(expand('%:p'))], ale#engine#FormatCommand(bufnr('%'), 'foo %s bar %s')
AssertEqual ['', 'foo ' . shellescape(expand('%:p')) . ' bar ' . shellescape(expand('%:p'))], ale#command#FormatCommand(bufnr('%'), 'foo %s bar %s', 0)
Execute(FormatCommand should convert %t to a new temporary filename):
let g:result = ale#engine#FormatCommand(bufnr('%'), 'foo %t bar %t')
let g:result = ale#command#FormatCommand(bufnr('%'), 'foo %t bar %t', 0)
let g:match = matchlist(g:result[1], '\v^foo (''/tmp/[^'']*/dummy.txt'') bar (''/tmp/[^'']*/dummy.txt'')$')
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
@ -27,7 +27,7 @@ Execute(FormatCommand should convert %t to a new temporary filename):
AssertEqual g:match[1], g:match[2]
Execute(FormatCommand should let you combine %s and %t):
let g:result = ale#engine#FormatCommand(bufnr('%'), 'foo %t bar %s')
let g:result = ale#command#FormatCommand(bufnr('%'), 'foo %t bar %s', 0)
let g:match = matchlist(g:result[1], '\v^foo (''/tmp/.*/dummy.txt'') bar (''.*/dummy.txt'')$')
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
@ -39,3 +39,14 @@ Execute(FormatCommand should let you combine %s and %t):
Execute(EscapeCommandPart should escape all percent signs):
AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%')
Execute(EscapeCommandPart should pipe in temporary files appropriately):
let g:result = ale#command#FormatCommand(bufnr('%'), 'foo bar', 1)
let g:match = matchlist(g:result[1], '\v^foo bar \< (''/tmp/[^'']*/dummy.txt'')$')
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual shellescape(g:result[0]), g:match[1]
let g:result = ale#command#FormatCommand(bufnr('%'), 'foo bar %t', 1)
let g:match = matchlist(g:result[1], '\v^foo bar (''/tmp/[^'']*/dummy.txt'')$')
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual shellescape(g:result[0]), g:match[1]