summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale/command.vim24
-rw-r--r--doc/ale.txt12
-rw-r--r--test/test_format_command.vader37
3 files changed, 67 insertions, 6 deletions
diff --git a/autoload/ale/command.vim b/autoload/ale/command.vim
index ec264a36..8f497169 100644
--- a/autoload/ale/command.vim
+++ b/autoload/ale/command.vim
@@ -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 %.
diff --git a/doc/ale.txt b/doc/ale.txt
index 7327959b..ac51e466 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -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
diff --git a/test/test_format_command.vader b/test/test_format_command.vader
index f8e2a66e..9d730fce 100644
--- a/test/test_format_command.vader
+++ b/test/test_format_command.vader
@@ -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]