#2556 - Support modifiers for formatted filenames

This commit is contained in:
w0rp
2020-08-24 09:33:07 +01:00
parent 1a7366067a
commit 3e2abe3f25
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, " Format a filename, converting it with filename mappings, if non-empty,
" and escaping it for putting into a command string. " 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 let l:filename = a:filename
if !empty(a:mappings) if !empty(a:mappings)
let l:filename = ale#filename_mapping#Map(l:filename, a:mappings) let l:filename = ale#filename_mapping#Map(l:filename, a:mappings)
endif endif
if !empty(a:modifiers)
let l:filename = fnamemodify(l:filename, a:modifiers)
endif
return ale#Escape(l:filename) return ale#Escape(l:filename)
endfunction endfunction
@@ -155,7 +161,7 @@ function! ale#command#FormatCommand(
\ command, \ command,
\ pipe_file_if_needed, \ pipe_file_if_needed,
\ input, \ input,
\ filename_mappings, \ mappings,
\) abort \) abort
let l:temporary_file = '' let l:temporary_file = ''
let l:command = a:command let l:command = a:command
@@ -173,14 +179,24 @@ function! ale#command#FormatCommand(
" file. " file.
if l:command =~# '%s' if l:command =~# '%s'
let l:filename = fnamemodify(bufname(a:buffer), ':p') 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 endif
if a:input isnot v:false && l:command =~# '%t' if a:input isnot v:false && l:command =~# '%t'
" Create a temporary filename, <temp_dir>/<original_basename> " Create a temporary filename, <temp_dir>/<original_basename>
" The file itself will not be created by this function. " The file itself will not be created by this function.
let l:temporary_file = s:TemporaryFilename(a:buffer) 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 endif
" Finish formatting so %% becomes %. " 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 file will be created, containing the lines from the file
after previous adjustment have been done. 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 `read_temporary_file` When set to `1`, ALE will read the contents of the
temporary file created for `%t`. This option can be used temporary file created for `%t`. This option can be used
for commands which need to modify some file on disk in 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 command, so literal character sequences `%s` and `%t` can be escaped by
using `%%s` and `%%t` instead, etc. 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 If a callback for a command generates part of a command string which might
possibly contain `%%`, `%s`, `%t`, or `%e`, where the special formatting possibly contain `%%`, `%s`, `%t`, or `%e`, where the special formatting
behavior is not desired, the |ale#command#EscapeCommandPart()| function can 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] Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual ale#Escape(g:result[0]), g:match[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): 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'], \ [expand('%:p:h'), '/foo/bar'],
\]) \])
Assert g:result[1] =~# '/foo/bar' Assert g:result[1] =~# '/foo/bar'
Execute(FormatCommand should apply filename mappings to temporary files): 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'] \ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
\]) \])
Assert g:result[1] =~# '/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]