#2556 - Support modifiers for formatted filenames

This commit is contained in:
w0rp 2020-08-24 09:33:07 +01:00
parent 1a7366067a
commit 3e2abe3f25
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
3 changed files with 67 additions and 6 deletions

View File

@ -135,13 +135,19 @@ endfunction
" Format a filename, converting it with filename mappings, if non-empty,
" and escaping it for putting into a command string.
function! s:FormatFilename(filename, mappings) abort
"
" The filename can be modified.
function! s:FormatFilename(filename, mappings, modifiers) abort
let l:filename = a:filename
if !empty(a:mappings)
let l:filename = ale#filename_mapping#Map(l:filename, a:mappings)
endif
if !empty(a:modifiers)
let l:filename = fnamemodify(l:filename, a:modifiers)
endif
return ale#Escape(l:filename)
endfunction
@ -155,7 +161,7 @@ function! ale#command#FormatCommand(
\ command,
\ pipe_file_if_needed,
\ input,
\ filename_mappings,
\ mappings,
\) abort
let l:temporary_file = ''
let l:command = a:command
@ -173,14 +179,24 @@ function! ale#command#FormatCommand(
" file.
if l:command =~# '%s'
let l:filename = fnamemodify(bufname(a:buffer), ':p')
let l:command = substitute(l:command, '%s', '\=s:FormatFilename(l:filename, a:filename_mappings)', 'g')
let l:command = substitute(
\ l:command,
\ '\v\%s(%(:h|:t|:r|:e)*)',
\ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))',
\ 'g'
\)
endif
if a:input isnot v:false && 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', '\=s:FormatFilename(l:temporary_file, a:filename_mappings)', 'g')
let l:command = substitute(
\ l:command,
\ '\v\%t(%(:h|:t|:r|:e)*)',
\ '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))',
\ 'g'
\)
endif
" Finish formatting so %% becomes %.

View File

@ -342,6 +342,8 @@ are supported for running the commands.
file will be created, containing the lines from the file
after previous adjustment have been done.
See |ale-command-format-strings| for formatting options.
`read_temporary_file` When set to `1`, ALE will read the contents of the
temporary file created for `%t`. This option can be used
for commands which need to modify some file on disk in
@ -3739,6 +3741,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
command, so literal character sequences `%s` and `%t` can be escaped by
using `%%s` and `%%t` instead, etc.
Some |filename-modifiers| can be applied to `%s` and `%t`. Only `:h`, `:t`,
`:r`, and `:e` may be applied, other modifiers will be ignored. Filename
modifiers can be applied to the format markers by placing them after them.
For example: >
'command': '%s:h %s:e %s:h:t',
<
Given a path `/foo/baz/bar.txt`, the above command string will generate
something akin to `'/foo/baz' 'txt' 'baz'`
If a callback for a command generates part of a command string which might
possibly contain `%%`, `%s`, `%t`, or `%e`, where the special formatting
behavior is not desired, the |ale#command#EscapeCommandPart()| function can

View File

@ -126,16 +126,49 @@ Execute(EscapeCommandPart should pipe in temporary files appropriately):
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual ale#Escape(g:result[0]), g:match[1]
Execute(FormatCommand should apply filename modifiers to the current file):
AssertEqual
\ ale#Escape(expand('%:p:h'))
\ . ' ' . ale#Escape('dummy.txt')
\ . ' ' . ale#Escape(expand('%:p:h:t'))
\ . ' ' . ale#Escape('txt')
\ . ' ' . ale#Escape(expand('%:p:r')),
\ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, [])[1]
Execute(FormatCommand should apply filename modifiers to the temporary file):
let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, [])
AssertEqual
\ ale#Escape(fnamemodify(g:result[0], ':h'))
\ . ' ' . ale#Escape('dummy.txt')
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':h:t'))
\ . ' ' . ale#Escape('txt')
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':r')),
\ g:result[1]
Execute(FormatCommand should apply filename mappings the current file):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 1, v:null, [
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, [
\ [expand('%:p:h'), '/foo/bar'],
\])
Assert g:result[1] =~# '/foo/bar'
Execute(FormatCommand should apply filename mappings to temporary files):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 1, v:null, [
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, [
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
\])
Assert g:result[1] =~# '/foo/bar'
Execute(FormatCommand should apply filename modifiers to mapped filenames):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, [
\ [expand('%:p:h'), '/foo/bar'],
\])
AssertEqual ale#Escape('/foo/bar'), g:result[1]
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, [
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
\])
AssertEqual ale#Escape('/foo/bar'), g:result[1]