Merge branch 'custom-erlc-executable'

This commit is contained in:
pinicarus
2020-11-01 11:45:36 +01:00
29 changed files with 361 additions and 93 deletions

View File

@@ -1,14 +1,22 @@
" Author: Magnus Ottenklinger - https://github.com/evnu " Author: Magnus Ottenklinger - https://github.com/evnu
let g:ale_erlang_erlc_executable = get(g:, 'ale_erlang_erlc_executable', 'erlc')
let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '') let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
function! ale_linters#erlang#erlc#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'erlang_erlc_executable')
endfunction
function! ale_linters#erlang#erlc#GetCommand(buffer) abort function! ale_linters#erlang#erlc#GetCommand(buffer) abort
let l:output_file = ale#util#Tempname() let l:output_file = ale#util#Tempname()
call ale#command#ManageFile(a:buffer, l:output_file) call ale#command#ManageFile(a:buffer, l:output_file)
return 'erlc -o ' . ale#Escape(l:output_file) let l:command = ale#Escape(ale_linters#erlang#erlc#GetExecutable(a:buffer))
\ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options') \ . ' -o ' . ale#Escape(l:output_file)
\ . ' %t' \ . ' ' . ale#Var(a:buffer, 'erlang_erlc_options')
\ . ' %t'
return l:command
endfunction endfunction
function! ale_linters#erlang#erlc#Handle(buffer, lines) abort function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
@@ -90,7 +98,7 @@ endfunction
call ale#linter#Define('erlang', { call ale#linter#Define('erlang', {
\ 'name': 'erlc', \ 'name': 'erlc',
\ 'executable': 'erlc', \ 'executable': function('ale_linters#erlang#erlc#GetExecutable'),
\ 'command': function('ale_linters#erlang#erlc#GetCommand'), \ 'command': function('ale_linters#erlang#erlc#GetCommand'),
\ 'callback': 'ale_linters#erlang#erlc#Handle', \ 'callback': 'ale_linters#erlang#erlc#Handle',
\}) \})

View File

@@ -9,13 +9,7 @@ call ale#Set('java_javac_classpath', '')
call ale#Set('java_javac_sourcepath', '') call ale#Set('java_javac_sourcepath', '')
function! ale_linters#java#javac#RunWithImportPaths(buffer) abort function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = '' let l:command = ale#maven#BuildClasspathCommand(a:buffer)
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
" Try to use Gradle if Maven isn't available. " Try to use Gradle if Maven isn't available.
if empty(l:command) if empty(l:command)

View File

@@ -1,26 +1,33 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com> " Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Code action support for LSP / tsserver " Description: Code action support for LSP / tsserver
function! ale#code_action#HandleCodeAction(code_action, should_save) abort function! ale#code_action#HandleCodeAction(code_action, options) abort
let l:current_buffer = bufnr('') let l:current_buffer = bufnr('')
let l:changes = a:code_action.changes let l:changes = a:code_action.changes
let l:should_save = get(a:options, 'should_save')
let l:force_save = get(a:options, 'force_save')
let l:safe_changes = []
for l:file_code_edit in l:changes for l:file_code_edit in l:changes
let l:buf = bufnr(l:file_code_edit.fileName) let l:buf = bufnr(l:file_code_edit.fileName)
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod') if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
call ale#util#Execute('echom ''Aborting action, file is unsaved''') if !l:force_save
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
return return
endif
else
call add(l:safe_changes, l:file_code_edit)
endif endif
endfor endfor
for l:file_code_edit in l:changes for l:file_code_edit in l:safe_changes
call ale#code_action#ApplyChanges( call ale#code_action#ApplyChanges(
\ l:file_code_edit.fileName, \ l:file_code_edit.fileName,
\ l:file_code_edit.textChanges, \ l:file_code_edit.textChanges,
\ a:should_save, \ l:should_save,
\ ) \)
endfor endfor
endfunction endfunction

View File

@@ -1006,7 +1006,7 @@ function! ale#completion#HandleUserData(completed_item) abort
\|| l:source is# 'ale-import' \|| l:source is# 'ale-import'
\|| l:source is# 'ale-omnifunc' \|| l:source is# 'ale-omnifunc'
for l:code_action in get(l:user_data, 'code_actions', []) for l:code_action in get(l:user_data, 'code_actions', [])
call ale#code_action#HandleCodeAction(l:code_action, v:false) call ale#code_action#HandleCodeAction(l:code_action, {})
endfor endfor
endif endif

51
autoload/ale/maven.vim Normal file
View File

@@ -0,0 +1,51 @@
" Description: Functions for working with Maven projects.
"
" Given a buffer number, find a Maven project root.
function! ale#maven#FindProjectRoot(buffer) abort
let l:wrapper_path = ale#path#FindNearestFile(a:buffer, 'mvnw')
if !empty(l:wrapper_path)
return fnamemodify(l:wrapper_path, ':h')
endif
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path)
return fnamemodify(l:pom_path, ':h')
endif
return ''
endfunction
" Given a buffer number, find the path to the executable.
" First search on the path for 'mvnw' (mvnw.cmd on Windows), if nothing is found,
" try the global command. Returns an empty string if cannot find the executable.
function! ale#maven#FindExecutable(buffer) abort
let l:wrapper_cmd = has('unix') ? 'mvnw' : 'mvnw.cmd'
let l:wrapper_path = ale#path#FindNearestFile(a:buffer, l:wrapper_cmd)
if executable(l:wrapper_path)
return l:wrapper_path
endif
if executable('mvn')
return 'mvn'
endif
return ''
endfunction
" Given a buffer number, build a command to print the classpath of the root
" project. Returns an empty string if cannot build the command.
function! ale#maven#BuildClasspathCommand(buffer) abort
let l:executable = ale#maven#FindExecutable(a:buffer)
let l:project_root = ale#maven#FindProjectRoot(a:buffer)
if !empty(l:executable) && !empty(l:project_root)
return ale#path#CdString(l:project_root)
\ . l:executable . ' dependency:build-classpath'
endif
return ''
endfunction

View File

@@ -12,10 +12,13 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
let l:file_code_edits = a:response.body let l:file_code_edits = a:response.body
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ 'description': 'Organize Imports', \ {
\ 'changes': l:file_code_edits, \ 'description': 'Organize Imports',
\}, v:false) \ 'changes': l:file_code_edits,
\ },
\ {}
\)
endfunction endfunction
function! s:OnReady(linter, lsp_details) abort function! s:OnReady(linter, lsp_details) abort

View File

@@ -33,9 +33,10 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
return return
endif endif
let l:old_name = s:rename_map[a:response.request_seq].old_name let l:options = remove(s:rename_map, a:response.request_seq)
let l:new_name = s:rename_map[a:response.request_seq].new_name
call remove(s:rename_map, a:response.request_seq) let l:old_name = l:options.old_name
let l:new_name = l:options.new_name
if get(a:response, 'success', v:false) is v:false if get(a:response, 'success', v:false) is v:false
let l:message = get(a:response, 'message', 'unknown') let l:message = get(a:response, 'message', 'unknown')
@@ -77,10 +78,16 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort
return return
endif endif
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ 'description': 'rename', \ {
\ 'changes': l:changes, \ 'description': 'rename',
\}, v:true) \ 'changes': l:changes,
\ },
\ {
\ 'should_save': 1,
\ 'force_save': get(l:options, 'force_save'),
\ },
\)
endfunction endfunction
function! s:getChanges(workspace_edit) abort function! s:getChanges(workspace_edit) abort
@@ -111,7 +118,7 @@ endfunction
function! ale#rename#HandleLSPResponse(conn_id, response) abort function! ale#rename#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id') if has_key(a:response, 'id')
\&& has_key(s:rename_map, a:response.id) \&& has_key(s:rename_map, a:response.id)
call remove(s:rename_map, a:response.id) let l:options = remove(s:rename_map, a:response.id)
if !has_key(a:response, 'result') if !has_key(a:response, 'result')
call s:message('No rename result received from server') call s:message('No rename result received from server')
@@ -156,14 +163,20 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort
\}) \})
endfor endfor
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ 'description': 'rename', \ {
\ 'changes': l:changes, \ 'description': 'rename',
\}, v:true) \ 'changes': l:changes,
\ },
\ {
\ 'should_save': 1,
\ 'force_save': get(l:options, 'force_save'),
\ },
\)
endif endif
endfunction endfunction
function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort function! s:OnReady(line, column, options, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id let l:id = a:lsp_details.connection_id
if !ale#lsp#HasCapability(l:id, 'rename') if !ale#lsp#HasCapability(l:id, 'rename')
@@ -195,19 +208,16 @@ function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort
\ l:buffer, \ l:buffer,
\ a:line, \ a:line,
\ a:column, \ a:column,
\ a:new_name \ a:options.new_name
\) \)
endif endif
let l:request_id = ale#lsp#Send(l:id, l:message) let l:request_id = ale#lsp#Send(l:id, l:message)
let s:rename_map[l:request_id] = { let s:rename_map[l:request_id] = a:options
\ 'new_name': a:new_name,
\ 'old_name': a:old_name,
\}
endfunction endfunction
function! s:ExecuteRename(linter, old_name, new_name) abort function! s:ExecuteRename(linter, options) abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2] let [l:line, l:column] = getpos('.')[1:2]
@@ -215,12 +225,11 @@ function! s:ExecuteRename(linter, old_name, new_name) abort
let l:column = min([l:column, len(getline(l:line))]) let l:column = min([l:column, len(getline(l:line))])
endif endif
let l:Callback = function( let l:Callback = function('s:OnReady', [l:line, l:column, a:options])
\ 's:OnReady', [l:line, l:column, a:old_name, a:new_name])
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback) call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
endfunction endfunction
function! ale#rename#Execute() abort function! ale#rename#Execute(options) abort
let l:lsp_linters = [] let l:lsp_linters = []
for l:linter in ale#linter#Get(&filetype) for l:linter in ale#linter#Get(&filetype)
@@ -245,6 +254,10 @@ function! ale#rename#Execute() abort
endif endif
for l:lsp_linter in l:lsp_linters for l:lsp_linter in l:lsp_linters
call s:ExecuteRename(l:lsp_linter, l:old_name, l:new_name) call s:ExecuteRename(l:lsp_linter, {
\ 'old_name': l:old_name,
\ 'new_name': l:new_name,
\ 'force_save': get(a:options, 'force_save') is 1,
\})
endfor endfor
endfunction endfunction

View File

@@ -42,6 +42,14 @@ g:ale_erlang_dialyzer_rebar3_profile *g:ale_erlang_dialyzer_rebar3_profile*
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
erlc *ale-erlang-erlc* erlc *ale-erlang-erlc*
g:ale_erlang_erlc_executable *g:ale_erlang_erlc_executable*
*b:ale_erlang_erlc_executable*
Type: |String|
Default: `'erlc'`
This variable can be changed to specify the erlc executable.
g:ale_erlang_erlc_options *g:ale_erlang_erlc_options* g:ale_erlang_erlc_options *g:ale_erlang_erlc_options*
*b:ale_erlang_erlc_options* *b:ale_erlang_erlc_options*
Type: |String| Type: |String|

View File

@@ -455,9 +455,9 @@ Notes:
* SugarSS * SugarSS
* `stylelint` * `stylelint`
* Swift * Swift
* Apple `swift-format`
* `sourcekit-lsp` * `sourcekit-lsp`
* `swiftformat` * `swiftformat`
* `swift-format`
* `swiftlint` * `swiftlint`
* Tcl * Tcl
* `nagelfar`!! * `nagelfar`!!

View File

@@ -154,7 +154,7 @@ Any existing problems will be kept.
3.1 Linting On Other Machines *ale-lint-other-machines* 3.1 Linting On Other Machines *ale-lint-other-machines*
ALE offers support for running linters or fixers on files you are editing ALE offers support for running linters or fixers on files you are editing
locally on other machines, so long as the other machine has access the file locally on other machines, so long as the other machine has access to the file
you are editing. This could be a linter or fixer run inside of a Docker image, you are editing. This could be a linter or fixer run inside of a Docker image,
running in a virtual machine, running on a remote server, etc. running in a virtual machine, running on a remote server, etc.
@@ -3099,6 +3099,12 @@ ALERename *ALERename*
The symbol where the cursor is resting will be the symbol renamed, and a The symbol where the cursor is resting will be the symbol renamed, and a
prompt will open to request a new name. prompt will open to request a new name.
ALE will refuse to complete a rename operation if there are files to modify
which have not yet been saved in Vim. If the command is run with a bang
(`:ALERename!`), all warnings will be suppressed, and files that are still
open in Vim and not saved will be ignored and left in a state where symbols
in those files will not be updated.
ALERepeatSelection *ALERepeatSelection* ALERepeatSelection *ALERepeatSelection*

View File

@@ -238,7 +238,7 @@ command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual')
command! -bar ALEImport :call ale#completion#Import() command! -bar ALEImport :call ale#completion#Import()
" Rename symbols using tsserver and LSP " Rename symbols using tsserver and LSP
command! -bar ALERename :call ale#rename#Execute() command! -bar -bang ALERename :call ale#rename#Execute({'force_save': '<bang>' is# '!'})
" Organize import statements using tsserver " Organize import statements using tsserver
command! -bar ALEOrganizeImports :call ale#organize_imports#Execute() command! -bar ALEOrganizeImports :call ale#organize_imports#Execute()

View File

@@ -464,9 +464,9 @@ formatting.
* SugarSS * SugarSS
* [stylelint](https://github.com/stylelint/stylelint) * [stylelint](https://github.com/stylelint/stylelint)
* Swift * Swift
* [Apple swift-format](https://github.com/apple/swift-format)
* [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) * [sourcekit-lsp](https://github.com/apple/sourcekit-lsp)
* [swiftformat](https://github.com/nicklockwood/SwiftFormat) * [swiftformat](https://github.com/nicklockwood/SwiftFormat)
* [swift-format](https://github.com/apple/swift-format)
* [swiftlint](https://github.com/realm/SwiftLint) * [swiftlint](https://github.com/realm/SwiftLint)
* Tcl * Tcl
* [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk: * [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk:

View File

@@ -0,0 +1,40 @@
Before:
call ale#assert#SetUpLinterTest('erlang', 'erlc')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct.):
let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
let g:regex = 'erlc.\+-o.\+%t'
let g:matched = match(g:cmd, g:regex)
" match returns -1 if not found
AssertNotEqual
\ g:matched,
\ -1,
\ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'
Execute(The command should accept configured executable.):
let b:ale_erlang_erlc_executable = '/usr/bin/erlc'
let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
let g:regex = '/usr/bin/erlc.\+-o.\+%t'
let g:matched = match(g:cmd, g:regex)
" match returns -1 if not found
AssertNotEqual
\ g:matched,
\ -1,
\ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'
Execute(The command should accept configured options.):
let b:ale_erlang_erlc_options = '-I include'
let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
let g:regex = 'erlc.\+-o.\+-I include.\+%t'
let g:matched = match(g:cmd, g:regex)
" match returns -1 if not found
AssertNotEqual
\ g:matched,
\ -1,
\ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'

View File

@@ -65,8 +65,8 @@ Before:
return g:server_started_value return g:server_started_value
endfunction endfunction
function! ale#code_action#HandleCodeAction(code_action, should_save) abort function! ale#code_action#HandleCodeAction(code_action, options) abort
Assert !a:should_save Assert !get(a:options, 'should_save')
call add(g:code_action_list, a:code_action) call add(g:code_action_list, a:code_action)
endfunction endfunction

View File

@@ -50,8 +50,8 @@ Before:
let g:handle_code_action_called = 0 let g:handle_code_action_called = 0
function! MockHandleCodeAction() abort function! MockHandleCodeAction() abort
" delfunction! ale#code_action#HandleCodeAction " delfunction! ale#code_action#HandleCodeAction
function! ale#code_action#HandleCodeAction(action, should_save) abort function! ale#code_action#HandleCodeAction(action, options) abort
AssertEqual v:false, a:should_save Assert !get(a:options, 'should_save')
let g:handle_code_action_called += 1 let g:handle_code_action_called += 1
endfunction endfunction
endfunction endfunction

View File

View File

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

0
test/maven-test-files/mvn Executable file
View File

View File

@@ -85,7 +85,8 @@ Execute(It should modify and save multiple files):
\ 'import D from "D"', \ 'import D from "D"',
\], g:file2, 'S') \], g:file2, 'S')
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ {
\ 'changes': [{ \ 'changes': [{
\ 'fileName': g:file1, \ 'fileName': g:file1,
\ 'textChanges': [{ \ 'textChanges': [{
@@ -122,8 +123,10 @@ Execute(It should modify and save multiple files):
\ }, \ },
\ 'newText': "import {A, B} from 'module'\n\n", \ 'newText': "import {A, B} from 'module'\n\n",
\ }] \ }]
\ }], \ }],
\}, v:true) \ },
\ {'should_save': 1},
\)
AssertEqual [ AssertEqual [
\ 'class Value {', \ 'class Value {',
@@ -153,7 +156,8 @@ Execute(Beginning of file can be modified):
\] \]
call writefile(g:test.text, g:file1, 'S') call writefile(g:test.text, g:file1, 'S')
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ {
\ 'changes': [{ \ 'changes': [{
\ 'fileName': g:file1, \ 'fileName': g:file1,
\ 'textChanges': [{ \ 'textChanges': [{
@@ -168,7 +172,9 @@ Execute(Beginning of file can be modified):
\ 'newText': "type A: string\ntype B: number\n", \ 'newText': "type A: string\ntype B: number\n",
\ }], \ }],
\ }] \ }]
\}, v:true) \ },
\ {'should_save': 1},
\)
AssertEqual [ AssertEqual [
\ 'type A: string', \ 'type A: string',
@@ -184,22 +190,25 @@ Execute(End of file can be modified):
\] \]
call writefile(g:test.text, g:file1, 'S') call writefile(g:test.text, g:file1, 'S')
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ {
\ 'changes': [{ \ 'changes': [{
\ 'fileName': g:file1, \ 'fileName': g:file1,
\ 'textChanges': [{ \ 'textChanges': [{
\ 'start': { \ 'start': {
\ 'line': 4, \ 'line': 4,
\ 'offset': 1, \ 'offset': 1,
\ }, \ },
\ 'end': { \ 'end': {
\ 'line': 4, \ 'line': 4,
\ 'offset': 1, \ 'offset': 1,
\ }, \ },
\ 'newText': "type A: string\ntype B: number\n", \ 'newText': "type A: string\ntype B: number\n",
\ }], \ }],
\ }] \ }]
\}, v:true) \ },
\ {'should_save': 1},
\)
AssertEqual g:test.text + [ AssertEqual g:test.text + [
\ 'type A: string', \ 'type A: string',
@@ -219,7 +228,8 @@ Execute(Current buffer contents will be reloaded):
execute 'edit ' . g:file1 execute 'edit ' . g:file1
let g:test.buffer = bufnr(g:file1) let g:test.buffer = bufnr(g:file1)
call ale#code_action#HandleCodeAction({ call ale#code_action#HandleCodeAction(
\ {
\ 'changes': [{ \ 'changes': [{
\ 'fileName': g:file1, \ 'fileName': g:file1,
\ 'textChanges': [{ \ 'textChanges': [{
@@ -234,7 +244,9 @@ Execute(Current buffer contents will be reloaded):
\ 'newText': "type A: string\ntype B: number\n", \ 'newText': "type A: string\ntype B: number\n",
\ }], \ }],
\ }] \ }]
\}, v:true) \ },
\ {'should_save': 1},
\)
AssertEqual [ AssertEqual [
\ 'type A: string', \ 'type A: string',
@@ -256,11 +268,11 @@ Execute(Cursor will not move when it is before text change):
let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2') let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2')
call setpos('.', [0, 1, 1, 0]) call setpos('.', [0, 1, 1, 0])
call ale#code_action#HandleCodeAction(g:test.changes, v:true) call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual [1, 1], getpos('.')[1:2] AssertEqual [1, 1], getpos('.')[1:2]
call setpos('.', [0, 2, 2, 0]) call setpos('.', [0, 2, 2, 0])
call ale#code_action#HandleCodeAction(g:test.changes, v:true) call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual [2, 2], getpos('.')[1:2] AssertEqual [2, 2], getpos('.')[1:2]
# ====C==== # ====C====
@@ -271,7 +283,7 @@ Execute(Cursor column will move to the change end when cursor between start/end)
call WriteFileAndEdit() call WriteFileAndEdit()
call setpos('.', [0, 2, r, 0]) call setpos('.', [0, 2, r, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(g:test.changes, v:true) call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual ' value2: string', getline('.') AssertEqual ' value2: string', getline('.')
AssertEqual [2, 9], getpos('.')[1:2] AssertEqual [2, 9], getpos('.')[1:2]
endfor endfor
@@ -283,7 +295,9 @@ Execute(Cursor column will move back when new text is shorter):
call setpos('.', [0, 2, 8, 0]) call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 3, 2, 8, 'val'), v:true) \ g:test.create_change(2, 3, 2, 8, 'val'),
\ {'should_save': 1},
\)
AssertEqual ' val: string', getline('.') AssertEqual ' val: string', getline('.')
AssertEqual [2, 6], getpos('.')[1:2] AssertEqual [2, 6], getpos('.')[1:2]
@@ -295,7 +309,7 @@ Execute(Cursor column will move forward when new text is longer):
call setpos('.', [0, 2, 8, 0]) call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 3, 2, 8, 'longValue'), v:true) \ g:test.create_change(2, 3, 2, 8, 'longValue'), {'should_save': 1})
AssertEqual ' longValue: string', getline('.') AssertEqual ' longValue: string', getline('.')
AssertEqual [2, 12], getpos('.')[1:2] AssertEqual [2, 12], getpos('.')[1:2]
@@ -307,7 +321,7 @@ Execute(Cursor line will move when updates are happening on lines above):
call setpos('.', [0, 3, 1, 0]) call setpos('.', [0, 3, 1, 0])
AssertEqual '}', getline('.') AssertEqual '}', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), v:true) \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), {'should_save': 1})
AssertEqual '}', getline('.') AssertEqual '}', getline('.')
AssertEqual [4, 1], getpos('.')[1:2] AssertEqual [4, 1], getpos('.')[1:2]
@@ -319,7 +333,7 @@ Execute(Cursor line and column will move when change on lines above and just bef
call setpos('.', [0, 2, 2, 0]) call setpos('.', [0, 2, 2, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), v:true) \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), {'should_save': 1})
AssertEqual '123 value: string', getline('.') AssertEqual '123 value: string', getline('.')
AssertEqual [3, 5], getpos('.')[1:2] AssertEqual [3, 5], getpos('.')[1:2]
@@ -331,7 +345,7 @@ Execute(Cursor line and column will move at the end of changes):
call setpos('.', [0, 2, 10, 0]) call setpos('.', [0, 2, 10, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 3, 1, "test\n"), v:true) \ g:test.create_change(1, 1, 3, 1, "test\n"), {'should_save': 1})
AssertEqual '}', getline('.') AssertEqual '}', getline('.')
AssertEqual [2, 1], getpos('.')[1:2] AssertEqual [2, 1], getpos('.')[1:2]
@@ -342,14 +356,14 @@ Execute(Cursor will not move when changes happening on lines >= cursor, but afte
call setpos('.', [0, 2, 3, 0]) call setpos('.', [0, 2, 3, 0])
AssertEqual ' value: string', getline('.') AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction( call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 10, 3, 1, "number\n"), v:true) \ g:test.create_change(2, 10, 3, 1, "number\n"), {'should_save': 1})
AssertEqual ' value: number', getline('.') AssertEqual ' value: number', getline('.')
AssertEqual [2, 3], getpos('.')[1:2] AssertEqual [2, 3], getpos('.')[1:2]
Execute(It should just modify file when should_save is set to v:false): Execute(It should just modify file when should_save is set to v:false):
call WriteFileAndEdit() call WriteFileAndEdit()
let g:test.change = g:test.create_change(1, 1, 1, 1, "import { writeFile } from 'fs';\n") let g:test.change = g:test.create_change(1, 1, 1, 1, "import { writeFile } from 'fs';\n")
call ale#code_action#HandleCodeAction(g:test.change, v:false) call ale#code_action#HandleCodeAction(g:test.change, {})
AssertEqual 1, getbufvar(bufnr(''), '&modified') AssertEqual 1, getbufvar(bufnr(''), '&modified')
AssertEqual [ AssertEqual [
\ 'import { writeFile } from ''fs'';', \ 'import { writeFile } from ''fs'';',

View File

@@ -0,0 +1,48 @@
Before:
Save $PATH
Save $PATHEXT
let $PATHEXT = '.'
call ale#test#SetDirectory('/testplugin/test')
runtime ale_linters/java/javac.vim
let g:expected_wrapper = ''
if has('unix')
let g:expected_wrapper = 'mvnw'
else
let g:expected_wrapper = 'mvnw.cmd'
endif
After:
Restore
unlet! g:expected_wrapper
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(Should use 'mvnw' in classpath command if available):
call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
AssertEqual
\ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1'))
\ . ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper)
\ . ' dependency:build-classpath',
\ ale#maven#BuildClasspathCommand(bufnr(''))
Execute(Should use 'mvn' in classpath command if it is executable and 'mvnw' is unavailable):
call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
let $PATH .= (has('win32') ? ';' : ':')
\ . ale#path#Simplify(g:dir . '/maven-test-files')
AssertEqual
\ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2'))
\ . 'mvn dependency:build-classpath',
\ ale#maven#BuildClasspathCommand(bufnr(''))
Execute(Should return empty string if maven cannot be executed):
call ale#test#SetFilename('maven-test-files/non-maven-project/src/main/java/dummy.java')
AssertEqual
\ '',
\ ale#maven#BuildClasspathCommand(bufnr(''))

View File

@@ -0,0 +1,46 @@
Before:
Save $PATH
Save $PATHEXT
" Count the maven executable without .exe as executable on Windows
let $PATHEXT = '.'
call ale#test#SetDirectory('/testplugin/test')
runtime ale_linters/java/javac.vim
let g:expected_wrapper = ''
if has('unix')
let g:expected_wrapper = 'mvnw'
else
let g:expected_wrapper = 'mvnw.cmd'
endif
After:
Restore
unlet! g:expected_wrapper
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(Should return 'mvnw' if found in parent directory):
call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
AssertEqual
\ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper),
\ ale#maven#FindExecutable(bufnr(''))
Execute(Should return 'mvn' if 'mvnw' not found in parent directory):
call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
let $PATH .= (has('win32') ? ';' : ':')
\ . ale#path#Simplify(g:dir . '/maven-test-files')
AssertEqual
\ 'mvn',
\ ale#maven#FindExecutable(bufnr(''))
Execute(Should return empty string if 'mvnw' not in parent directory and mvn not in path):
call ale#test#SetFilename('mvn-test-files/java-maven-project/module2/src/main/java/dummy2.java')
AssertEqual
\ '',
\ ale#gradle#FindExecutable(bufnr(''))

View File

@@ -0,0 +1,28 @@
Before:
call ale#test#SetDirectory('/testplugin/test')
runtime ale_linters/kotlin/javac.vim
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(Should return directory for 'mvnw' if found in parent directory):
call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
AssertEqual
\ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1'),
\ ale#maven#FindProjectRoot(bufnr(''))
Execute(Should return directory for 'pom.xml' if found in parent directory):
call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
AssertEqual
\ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2'),
\ ale#maven#FindProjectRoot(bufnr(''))
Execute(Should return empty string if maven files are not found in parent directory):
call ale#test#SetFilename('maven-test-files/non-maven-project/src/main/java/dummy.java')
AssertEqual
\ '',
\ ale#maven#FindProjectRoot(bufnr(''))

View File

@@ -57,9 +57,9 @@ Before:
call add(g:expr_list, a:expr) call add(g:expr_list, a:expr)
endfunction endfunction
function! ale#code_action#HandleCodeAction(code_action, should_save) abort function! ale#code_action#HandleCodeAction(code_action, options) abort
let g:handle_code_action_called = 1 let g:handle_code_action_called = 1
AssertEqual v:false, a:should_save Assert !get(a:options, 'should_save')
call add(g:code_actions, a:code_action) call add(g:code_actions, a:code_action)
endfunction endfunction

View File

@@ -57,9 +57,9 @@ Before:
call add(g:expr_list, a:expr) call add(g:expr_list, a:expr)
endfunction endfunction
function! ale#code_action#HandleCodeAction(code_action, should_save) abort function! ale#code_action#HandleCodeAction(code_action, options) abort
let g:handle_code_action_called = 1 let g:handle_code_action_called = 1
AssertEqual v:true, a:should_save Assert get(a:options, 'should_save')
call add(g:code_actions, a:code_action) call add(g:code_actions, a:code_action)
endfunction endfunction
@@ -269,7 +269,7 @@ Execute(tsserver rename requests should be sent):
\ }] \ }]
\ ], \ ],
\ g:message_list \ g:message_list
AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name'}}, AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name', 'force_save': 0}},
\ ale#rename#GetMap() \ ale#rename#GetMap()
Given python(Some Python file): Given python(Some Python file):
@@ -470,7 +470,7 @@ Execute(LSP rename requests should be sent):
let b:ale_linters = ['pyls'] let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0]) call setpos('.', [bufnr(''), 1, 5, 0])
ALERename ALERename!
" We shouldn't register the callback yet. " We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback) AssertEqual '''''', string(g:Callback)
@@ -500,5 +500,5 @@ Execute(LSP rename requests should be sent):
\ ], \ ],
\ g:message_list \ g:message_list
AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name'}}, AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name', 'force_save': 1}},
\ ale#rename#GetMap() \ ale#rename#GetMap()