diff --git a/autoload/ale/code_action.vim b/autoload/ale/code_action.vim index 917190be..65db6246 100644 --- a/autoload/ale/code_action.vim +++ b/autoload/ale/code_action.vim @@ -16,13 +16,12 @@ endfunction function! ale#code_action#HandleCodeAction(code_action, options) abort let l:current_buffer = bufnr('') let l:changes = a:code_action.changes - let l:should_save = get(a:options, 'should_save') for l:file_code_edit in l:changes call ale#code_action#ApplyChanges( \ l:file_code_edit.fileName, \ l:file_code_edit.textChanges, - \ l:should_save, + \ a:options, \) endfor endfunction @@ -63,29 +62,29 @@ function! s:ChangeCmp(left, right) abort return 0 endfunction -function! ale#code_action#ApplyChanges(filename, changes, should_save) abort - let l:current_buffer = bufnr('') +function! ale#code_action#ApplyChanges(filename, changes, options) abort + let l:should_save = get(a:options, 'should_save') + let l:conn_id = get(a:options, 'conn_id') + + let l:orig_buffer = bufnr('') + " The buffer is used to determine the fileformat, if available. let l:buffer = bufnr(a:filename) - let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer - if l:buffer > 0 - let l:lines = getbufline(l:buffer, 1, '$') - - " Add empty line if there's trailing newline, like readfile() does. - if getbufvar(l:buffer, '&eol') - let l:lines += [''] - endif - else - let l:lines = readfile(a:filename, 'b') + if l:buffer != l:orig_buffer + call ale#util#Execute('silent edit ' . a:filename) + let l:buffer = bufnr('') endif - if l:is_current_buffer - let l:pos = getpos('.')[1:2] - else - let l:pos = [1, 1] + let l:lines = getbufline(l:buffer, 1, '$') + + " Add empty line if there's trailing newline, like readfile() does. + if getbufvar(l:buffer, '&eol') + let l:lines += [''] endif + let l:pos = getpos('.')[1:2] + " Changes have to be sorted so we apply them from bottom-to-top for l:code_edit in reverse(sort(copy(a:changes), function('s:ChangeCmp'))) let l:line = l:code_edit.start.line @@ -155,46 +154,25 @@ function! ale#code_action#ApplyChanges(filename, changes, should_save) abort endif endfor - if l:buffer > 0 - " Make sure ale#util#{Writefile,SetBufferContents} add trailing - " newline if and only if it should be added. - if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol') - call remove(l:lines, -1) - else - call setbufvar(l:buffer, '&eol', 0) - endif - elseif exists('+fixeol') && &fixeol && l:lines[-1] is# '' - " Not in buffer, ale#util#Writefile can't check &eol and always adds - " newline if &fixeol: remove to prevent double trailing newline. + " Make sure to add a trailing newline if and only if it should be added. + if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol') call remove(l:lines, -1) - endif - - if a:should_save || l:buffer < 0 - call ale#util#Writefile(l:buffer, l:lines, a:filename) else - call ale#util#SetBufferContents(l:buffer, l:lines) + call setbufvar(l:buffer, '&eol', 0) endif - if l:is_current_buffer - if a:should_save - call ale#util#Execute(':e!') - endif + call ale#util#SetBufferContents(l:buffer, l:lines) - call setpos('.', [0, l:pos[0], l:pos[1], 0]) + call ale#lsp#NotifyForChanges(l:conn_id, l:buffer) + + if l:should_save + call ale#util#Execute('silent w!') endif - if a:should_save && l:buffer > 0 && !l:is_current_buffer - " Set up a one-time use event that will delete itself to reload the - " buffer next time it's entered to view the changes made to it. - execute 'augroup ALECodeActionReloadGroup' . l:buffer - autocmd! + call setpos('.', [0, l:pos[0], l:pos[1], 0]) - execute printf( - \ 'autocmd BufEnter ' - \ . ' call ale#code_action#ReloadBuffer()', - \ l:buffer - \) - augroup END + if l:orig_buffer != l:buffer && bufexists(l:orig_buffer) + call ale#util#Execute('silent buf ' . string(l:orig_buffer)) endif endfunction diff --git a/autoload/ale/organize_imports.vim b/autoload/ale/organize_imports.vim index e2b1c0d2..a6e77863 100644 --- a/autoload/ale/organize_imports.vim +++ b/autoload/ale/organize_imports.vim @@ -1,6 +1,6 @@ " Author: Jerko Steiner " Description: Organize imports support for tsserver -" + function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort if get(a:response, 'command', '') isnot# 'organizeImports' return @@ -17,7 +17,10 @@ function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort \ 'description': 'Organize Imports', \ 'changes': l:file_code_edits, \ }, - \ {} + \ { + \ 'conn_id': a:conn_id, + \ 'should_save': !&hidden, + \ }, \) endfunction diff --git a/autoload/ale/rename.vim b/autoload/ale/rename.vim index 9030618e..a722cc94 100644 --- a/autoload/ale/rename.vim +++ b/autoload/ale/rename.vim @@ -84,7 +84,8 @@ function! ale#rename#HandleTSServerResponse(conn_id, response) abort \ 'changes': l:changes, \ }, \ { - \ 'should_save': 1, + \ 'conn_id': a:conn_id, + \ 'should_save': !&hidden, \ }, \) endfunction @@ -116,7 +117,8 @@ function! ale#rename#HandleLSPResponse(conn_id, response) abort \ 'changes': l:changes, \ }, \ { - \ 'should_save': 1, + \ 'conn_id': a:conn_id, + \ 'should_save': !&hidden, \ }, \) endif diff --git a/doc/ale.txt b/doc/ale.txt index 6dbfb6d0..348cffaf 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1820,8 +1820,8 @@ g:ale_open_list *g:ale_open_list* autocmd! autocmd QuitPre * if empty(&buftype) | lclose | endif augroup END -< +< g:ale_pattern_options *g:ale_pattern_options* Type: |Dictionary| @@ -3435,6 +3435,10 @@ ALERename *ALERename* The symbol where the cursor is resting will be the symbol renamed, and a prompt will open to request a new name. + The rename operation will save all modified buffers when `set nohidden` is + set, because that disables leaving unsaved buffers in the background. See + `:help hidden` for more details. + ALEFileRename *ALEFileRename* Rename a file and fix imports using `tsserver`. diff --git a/test/test_code_action.vader b/test/test_code_action.vader index c613222c..80e2b1d8 100644 --- a/test/test_code_action.vader +++ b/test/test_code_action.vader @@ -1,4 +1,15 @@ Before: + let g:notified_changes = [] + + runtime autoload/ale/lsp.vim + + function! ale#lsp#NotifyForChanges(conn_id, buffer) abort + call add(g:notified_changes, { + \ 'conn_id': a:conn_id, + \ 'buffer': a:buffer + \}) + endfunction + Save g:ale_enabled let g:ale_enabled = 0 @@ -36,10 +47,10 @@ Before: After: " Close the extra buffers if we opened it. - if bufnr(g:file1) != -1 + if bufnr(g:file1) != -1 && buflisted(bufnr(g:file1)) execute ':bp! | :bd! ' . bufnr(g:file1) endif - if bufnr(g:file2) != -1 + if bufnr(g:file2) != -1 && buflisted(bufnr(g:file2)) execute ':bp! | :bd! ' . bufnr(g:file2) endif @@ -50,12 +61,16 @@ After: call delete(g:file2) endif + unlet! g:notified_changes + " unlet! g:expected_notified_changes unlet! g:file1 unlet! g:file2 unlet! g:test unlet! g:changes delfunction WriteFileAndEdit + runtime autoload/ale/lsp.vim + Restore @@ -118,7 +133,7 @@ Execute(It should modify and save multiple files): \ }] \ }], \ }, - \ {'should_save': 1}, + \ {'should_save': 1, 'conn_id': 'test_conn'}, \) AssertEqual [ @@ -140,6 +155,13 @@ Execute(It should modify and save multiple files): \ '', \], readfile(g:file2, 'b') + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file1), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file2), + \}], g:notified_changes Execute(Beginning of file can be modified): let g:test.text = [ @@ -166,7 +188,7 @@ Execute(Beginning of file can be modified): \ }], \ }] \ }, - \ {'should_save': 1}, + \ {'should_save': 1, 'conn_id': 'test_conn'}, \) AssertEqual [ @@ -174,6 +196,11 @@ Execute(Beginning of file can be modified): \ 'type B: number', \] + g:test.text + [''], readfile(g:file1, 'b') + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file1), + \}], g:notified_changes + Execute(End of file can be modified): let g:test.text = [ @@ -200,7 +227,7 @@ Execute(End of file can be modified): \ }], \ }] \ }, - \ {'should_save': 1}, + \ {'should_save': 1, 'conn_id': 'test_conn'}, \) AssertEqual g:test.text + [ @@ -209,6 +236,11 @@ Execute(End of file can be modified): \ '', \], readfile(g:file1, 'b') + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file1), + \}], g:notified_changes + Execute(Current buffer contents will be reloaded): let g:test.text = [ @@ -238,7 +270,7 @@ Execute(Current buffer contents will be reloaded): \ }], \ }] \ }, - \ {'should_save': 1}, + \ {'should_save': 1, 'conn_id': 'test_conn'}, \) AssertEqual [ @@ -251,6 +283,55 @@ Execute(Current buffer contents will be reloaded): \ 'type B: number', \] + g:test.text, getbufline(g:test.buffer, 1, '$') + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file1), + \}], g:notified_changes + + +Execute(Unlisted buffer contents will be modified correctly): + let g:test.text = [ + \ 'class Name {', + \ ' value: string', + \ '}', + \] + call writefile(g:test.text, g:file1, 'S') + + execute 'edit ' . g:file1 + let g:test.buffer = bufnr(g:file1) + + execute 'bd' + AssertEqual bufnr(g:file1), g:test.buffer + + call ale#code_action#HandleCodeAction( + \ { + \ 'changes': [{ + \ 'fileName': g:file1, + \ 'textChanges': [{ + \ 'start': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'end': { + \ 'line': 1, + \ 'offset': 1, + \ }, + \ 'newText': "type A: string\ntype B: number\n", + \ }], + \ }] + \ }, + \ {'should_save': 1, 'conn_id': 'test_conn'}, + \) + + AssertEqual [ + \ 'type A: string', + \ 'type B: number', + \] + g:test.text + [''], readfile(g:file1, 'b') + + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(g:file1), + \}], g:notified_changes # Tests for cursor repositioning. In comments `=` designates change range, and # `C` cursor position @@ -261,13 +342,32 @@ Execute(Cursor will not move when it is before text change): let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2') call setpos('.', [0, 1, 1, 0]) - call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + call ale#code_action#HandleCodeAction(g:test.changes, { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \}) AssertEqual [1, 1], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + call setpos('.', [0, 2, 2, 0]) - call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + call ale#code_action#HandleCodeAction(g:test.changes, { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \}) AssertEqual [2, 2], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ====C==== Execute(Cursor column will move to the change end when cursor between start/end): let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2') @@ -276,11 +376,34 @@ Execute(Cursor column will move to the change end when cursor between start/end) call WriteFileAndEdit() call setpos('.', [0, 2, r, 0]) AssertEqual ' value: string', getline('.') - call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1}) + call ale#code_action#HandleCodeAction(g:test.changes, { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \}) AssertEqual ' value2: string', getline('.') AssertEqual [2, 9], getpos('.')[1:2] endfor + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}, { + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ====C Execute(Cursor column will move back when new text is shorter): @@ -289,11 +412,18 @@ Execute(Cursor column will move back when new text is shorter): AssertEqual ' value: string', getline('.') call ale#code_action#HandleCodeAction( \ g:test.create_change(2, 3, 2, 8, 'val'), - \ {'should_save': 1}, - \) + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual ' val: string', getline('.') AssertEqual [2, 6], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ==== C Execute(Cursor column will move forward when new text is longer): @@ -302,10 +432,19 @@ Execute(Cursor column will move forward when new text is longer): call setpos('.', [0, 2, 8, 0]) AssertEqual ' value: string', getline('.') call ale#code_action#HandleCodeAction( - \ g:test.create_change(2, 3, 2, 8, 'longValue'), {'should_save': 1}) + \ g:test.create_change(2, 3, 2, 8, 'longValue'), + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual ' longValue: string', getline('.') AssertEqual [2, 12], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ========= # = # C @@ -314,10 +453,19 @@ Execute(Cursor line will move when updates are happening on lines above): call setpos('.', [0, 3, 1, 0]) AssertEqual '}', getline('.') call ale#code_action#HandleCodeAction( - \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), {'should_save': 1}) + \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual '}', getline('.') AssertEqual [4, 1], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ========= # =C @@ -326,10 +474,19 @@ Execute(Cursor line and column will move when change on lines above and just bef call setpos('.', [0, 2, 2, 0]) AssertEqual ' value: string', getline('.') call ale#code_action#HandleCodeAction( - \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), {'should_save': 1}) + \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual '123 value: string', getline('.') AssertEqual [3, 5], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # ========= # ======C== # = @@ -338,10 +495,19 @@ Execute(Cursor line and column will move at the end of changes): call setpos('.', [0, 2, 10, 0]) AssertEqual ' value: string', getline('.') call ale#code_action#HandleCodeAction( - \ g:test.create_change(1, 1, 3, 1, "test\n"), {'should_save': 1}) + \ g:test.create_change(1, 1, 3, 1, "test\n"), + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual '}', getline('.') AssertEqual [2, 1], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + # C == # === Execute(Cursor will not move when changes happening on lines >= cursor, but after cursor): @@ -349,23 +515,42 @@ Execute(Cursor will not move when changes happening on lines >= cursor, but afte call setpos('.', [0, 2, 3, 0]) AssertEqual ' value: string', getline('.') call ale#code_action#HandleCodeAction( - \ g:test.create_change(2, 10, 3, 1, "number\n"), {'should_save': 1}) + \ g:test.create_change(2, 10, 3, 1, "number\n"), + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual ' value: number', getline('.') AssertEqual [2, 3], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + Execute(Cursor will not move when change covers entire file): call WriteFileAndEdit() call setpos('.', [0, 2, 3, 0]) call ale#code_action#HandleCodeAction( \ g:test.create_change(1, 1, len(g:test.text) + 1, 1, \ join(g:test.text + ['x'], "\n")), - \ {'should_save': 1}) + \ { + \ 'should_save': 1, + \ 'conn_id': 'test_conn', + \ }) AssertEqual [2, 3], getpos('.')[1:2] + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + Execute(It should just modify file when should_save is set to v:false): call WriteFileAndEdit() 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, {}) + call ale#code_action#HandleCodeAction(g:test.change, { + \ 'conn_id': 'test_conn', + \}) AssertEqual 1, getbufvar(bufnr(''), '&modified') AssertEqual [ \ 'import { writeFile } from ''fs'';', @@ -374,6 +559,11 @@ Execute(It should just modify file when should_save is set to v:false): \ '}', \], getline(1, '$') + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes + Given typescript(An example TypeScript file): type Foo = {} @@ -393,7 +583,14 @@ Execute(): \ {'end': {'offset': 14, 'line': 9}, 'newText': 'foo', 'start': {'offset': 3, 'line': 9}}, \] - call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, { + \ 'conn_id': 'test_conn', + \}) + + AssertEqual [{ + \ 'conn_id': 'test_conn', + \ 'buffer': bufnr(''), + \}], g:notified_changes Expect(The changes should be applied correctly): type Foo = {} diff --git a/test/test_code_action_corner_cases.vader b/test/test_code_action_corner_cases.vader index c44cf0ea..7cdbba8a 100644 --- a/test/test_code_action_corner_cases.vader +++ b/test/test_code_action_corner_cases.vader @@ -34,20 +34,16 @@ Before: Save &fileformats set fileformats=unix - " two files, one accessed through a buffer, the other using write/readfile only - let g:files = [tempname(), tempname()] + let g:file = tempname() - function! TestChanges(contents, changes, mode) abort - let l:file = g:files[a:mode is 'file' ? 0 : 1] - call writefile(split(a:contents, '\n', 1), l:file, 'bS') - if a:mode isnot 'file' - execute 'edit ' . l:file - endif - call ale#code_action#ApplyChanges(l:file, a:changes, a:mode isnot 'buffer') - if a:mode is 'buffer' - execute 'write ' . l:file - endif - return join(readfile(l:file, 'b'), "\n") + function! TestChanges(contents, changes) abort + call writefile(split(a:contents, '\n', 1), g:file, 'bS') + + call ale#code_action#ApplyChanges(g:file, a:changes, { + \ 'should_save': 1, + \}) + + return join(readfile(g:file, 'b'), "\n") endfunction! function! MkPos(line, offset) abort @@ -63,17 +59,15 @@ Before: endfunction! After: - for g:file in g:files - if bufnr(g:file) != -1 - execute ':bp! | :bd! ' . bufnr(g:file) - endif - if filereadable(g:file) - call delete(g:file) - endif - endfor - unlet! g:files g:file + if bufnr(g:file) != -1 + execute ':bp! | :bd! ' . bufnr(g:file) + endif - unlet! g:mode + if filereadable(g:file) + call delete(g:file) + endif + + unlet! g:file delfunction TestChanges delfunction MkPos @@ -83,97 +77,67 @@ After: Restore Execute(Preserve (no)eol at eof): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "noeol", TestChanges("noeol", [], g:mode) - AssertEqual "eol\n", TestChanges("eol\n", [], g:mode) - AssertEqual "eols\n\n", TestChanges("eols\n\n", [], g:mode) - endfor - - " there doesn't seem to be a way to tell if a buffer is empty or contains one - " empty line :-( - AssertEqual "", TestChanges("", [], 'file') + AssertEqual "noeol", TestChanges("noeol", []) + AssertEqual "eol\n", TestChanges("eol\n", []) + AssertEqual "eols\n\n", TestChanges("eols\n\n", []) Execute(Respect fixeol): set fixeol - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - silent echo "vscode skip" | AssertEqual "noeol\n", TestChanges("noeol", [], g:mode) - silent echo "vscode skip" | AssertEqual "eol\n", TestChanges("eol\n", [], g:mode) - endfor + + silent echo "vscode skip" | AssertEqual "noeol\n", TestChanges("noeol", []) + silent echo "vscode skip" | AssertEqual "eol\n", TestChanges("eol\n", []) Execute(Add/del eol at eof): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "addeol\n", TestChanges("addeol", [MkInsert(MkPos(1, 7), "\n")], g:mode) - AssertEqual "deleol", TestChanges("deleol\n", [MkDelete(MkPos(1, 7), MkPos(1, 8))], g:mode) - endfor + AssertEqual "addeol\n", TestChanges("addeol", [MkInsert(MkPos(1, 7), "\n")]) + AssertEqual "deleol", TestChanges("deleol\n", [MkDelete(MkPos(1, 7), MkPos(1, 8))]) Execute(One character insertions to first line): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "xabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x")], g:mode) - AssertEqual "xabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x")], g:mode) - AssertEqual "axbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x")], g:mode) - AssertEqual "abcx\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x")], g:mode) - AssertEqual "abc\nxdef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x")], g:mode) - AssertEqual "abc\nxdef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x")], g:mode) - endfor + AssertEqual "xabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x")]) + AssertEqual "xabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x")]) + AssertEqual "axbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x")]) + AssertEqual "abcx\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x")]) + AssertEqual "abc\nxdef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x")]) + AssertEqual "abc\nxdef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x")]) Execute(One character + newline insertions to first line): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "x\nabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x\n")], g:mode) - AssertEqual "x\nabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x\n")], g:mode) - AssertEqual "ax\nbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x\n")], g:mode) - AssertEqual "abcx\n\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x\n")], g:mode) - AssertEqual "abc\nx\ndef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x\n")], g:mode) - AssertEqual "abc\nx\ndef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x\n")], g:mode) - endfor + AssertEqual "x\nabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x\n")]) + AssertEqual "x\nabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x\n")]) + AssertEqual "ax\nbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x\n")]) + AssertEqual "abcx\n\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x\n")]) + AssertEqual "abc\nx\ndef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x\n")]) + AssertEqual "abc\nx\ndef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x\n")]) Execute(One character insertions near end): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "abc\ndef1\nghxi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x")], g:mode) - AssertEqual "abc\ndef2\nghix\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x")], g:mode) - AssertEqual "abc\ndef3\nghi\nx", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x")], g:mode) - AssertEqual "abc\ndef4\nghi\nx", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x")], g:mode) - AssertEqual "abc\ndef5\nghi\nx", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x")], g:mode) - AssertEqual "abc\ndef6\nghi\nx", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x")], g:mode) - AssertEqual "abc\ndef7\nghi\nx", TestChanges("abc\ndef7\nghi\n", [MkInsert(MkPos(5, 1), "x")], g:mode) - AssertEqual "abc\ndef8\nghi\nx", TestChanges("abc\ndef8\nghi\n", [MkInsert(MkPos(5, 2), "x")], g:mode) - endfor + AssertEqual "abc\ndef1\nghxi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x")]) + AssertEqual "abc\ndef2\nghix\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x")]) + AssertEqual "abc\ndef3\nghi\nx", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x")]) + AssertEqual "abc\ndef4\nghi\nx", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x")]) + AssertEqual "abc\ndef5\nghi\nx", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x")]) + AssertEqual "abc\ndef6\nghi\nx", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x")]) + AssertEqual "abc\ndef7\nghi\nx", TestChanges("abc\ndef7\nghi\n", [MkInsert(MkPos(5, 1), "x")]) + AssertEqual "abc\ndef8\nghi\nx", TestChanges("abc\ndef8\nghi\n", [MkInsert(MkPos(5, 2), "x")]) Execute(One character + newline insertions near end): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "abc\ndef1\nghx\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x\n")], g:mode) - AssertEqual "abc\ndef2\nghix\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x\n")], g:mode) - AssertEqual "abc\ndef3\nghi\nx\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x\n")], g:mode) - AssertEqual "abc\ndef4\nghi\nx\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x\n")], g:mode) - AssertEqual "abc\ndef5\nghi\nx\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x\n")], g:mode) - AssertEqual "abc\ndef6\nghi\nx\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x\n")], g:mode) - endfor + AssertEqual "abc\ndef1\nghx\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x\n")]) + AssertEqual "abc\ndef2\nghix\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x\n")]) + AssertEqual "abc\ndef3\nghi\nx\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x\n")]) + AssertEqual "abc\ndef4\nghi\nx\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x\n")]) + AssertEqual "abc\ndef5\nghi\nx\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x\n")]) + AssertEqual "abc\ndef6\nghi\nx\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x\n")]) Execute(Newline insertions near end): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "abc\ndef1\ngh\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "\n")], g:mode) - AssertEqual "abc\ndef2\nghi\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "\n")], g:mode) - AssertEqual "abc\ndef3\nghi\n\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "\n")], g:mode) - AssertEqual "abc\ndef4\nghi\n\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "\n")], g:mode) - AssertEqual "abc\ndef5\nghi\n\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "\n")], g:mode) - endfor + AssertEqual "abc\ndef1\ngh\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "\n")]) + AssertEqual "abc\ndef2\nghi\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "\n")]) + AssertEqual "abc\ndef3\nghi\n\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "\n")]) + AssertEqual "abc\ndef4\nghi\n\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "\n")]) + AssertEqual "abc\ndef5\nghi\n\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "\n")]) Execute(Single char deletions): - for g:mode in ['save', 'file', 'buffer'] - Log g:mode - AssertEqual "bc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkDelete(MkPos(1, 1), MkPos(1, 2))], g:mode) - AssertEqual "ab\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkDelete(MkPos(1, 3), MkPos(1, 4))], g:mode) - AssertEqual "abcdef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 5))], g:mode) - AssertEqual "abcdef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 6))], g:mode) - AssertEqual "abc\ndef5\ngh\n", TestChanges("abc\ndef5\nghi\n", [MkDelete(MkPos(3, 3), MkPos(3, 4))], g:mode) - AssertEqual "abc\ndef6\nghi", TestChanges("abc\ndef6\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 5))], g:mode) - AssertEqual "abc\ndef7\nghi", TestChanges("abc\ndef7\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 6))], g:mode) - AssertEqual "abc\ndef8\nghi\n", TestChanges("abc\ndef8\nghi\n", [MkDelete(MkPos(4, 1), MkPos(4, 2))], g:mode) - endfor + AssertEqual "bc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkDelete(MkPos(1, 1), MkPos(1, 2))]) + AssertEqual "ab\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkDelete(MkPos(1, 3), MkPos(1, 4))]) + AssertEqual "abcdef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 5))]) + AssertEqual "abcdef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 6))]) + AssertEqual "abc\ndef5\ngh\n", TestChanges("abc\ndef5\nghi\n", [MkDelete(MkPos(3, 3), MkPos(3, 4))]) + AssertEqual "abc\ndef6\nghi", TestChanges("abc\ndef6\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 5))]) + AssertEqual "abc\ndef7\nghi", TestChanges("abc\ndef7\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 6))]) + AssertEqual "abc\ndef8\nghi\n", TestChanges("abc\ndef8\nghi\n", [MkDelete(MkPos(4, 1), MkPos(4, 2))]) diff --git a/test/test_code_action_python.vader b/test/test_code_action_python.vader index 2aac1ec7..3c784816 100644 --- a/test/test_code_action_python.vader +++ b/test/test_code_action_python.vader @@ -10,7 +10,7 @@ Execute(): \ {'end': {'offset': 15, 'line': 3}, 'newText': " return c\n\n\ndef main():\n c = func_qtffgsvi()\n", 'start': {'offset': 15, 'line': 3}} \] - call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, {}) Expect(The changes should be applied correctly): def func_qtffgsvi(): @@ -40,7 +40,7 @@ Execute(): \ {'end': {'offset': 42, 'line': 8}, 'newText': "ivlpdpao(f)\n", 'start': {'offset': 33, 'line': 6}} \] - call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0) + call ale#code_action#ApplyChanges(expand('%:p'), g:changes, {}) Expect(The changes should be applied correctly): import sys diff --git a/test/test_organize_imports.vader b/test/test_organize_imports.vader index 63973a54..87cd295a 100644 --- a/test/test_organize_imports.vader +++ b/test/test_organize_imports.vader @@ -59,7 +59,7 @@ Before: function! ale#code_action#HandleCodeAction(code_action, options) abort let g:handle_code_action_called = 1 - Assert !get(a:options, 'should_save') + AssertEqual !&hidden, get(a:options, 'should_save') call add(g:code_actions, a:code_action) endfunction diff --git a/test/test_rename.vader b/test/test_rename.vader index 42bcfd95..4298715f 100644 --- a/test/test_rename.vader +++ b/test/test_rename.vader @@ -59,7 +59,7 @@ Before: function! ale#code_action#HandleCodeAction(code_action, options) abort let g:handle_code_action_called = 1 - Assert get(a:options, 'should_save') + AssertEqual !&hidden, get(a:options, 'should_save', 0) call add(g:code_actions, a:code_action) endfunction