2020-11-14 10:15:17 +00:00
|
|
|
Before:
|
|
|
|
call ale#test#SetDirectory('/testplugin/test')
|
|
|
|
call ale#test#SetFilename('dummy.txt')
|
|
|
|
Save g:ale_buffer_info
|
|
|
|
|
|
|
|
let g:ale_buffer_info = {}
|
|
|
|
|
|
|
|
let g:old_filename = expand('%:p')
|
|
|
|
let g:Callback = ''
|
|
|
|
let g:expr_list = []
|
|
|
|
let g:message_list = []
|
|
|
|
let g:handle_code_action_called = 0
|
|
|
|
let g:code_actions = []
|
|
|
|
let g:options = {}
|
|
|
|
let g:capability_checked = ''
|
|
|
|
let g:conn_id = v:null
|
|
|
|
let g:InitCallback = v:null
|
|
|
|
|
|
|
|
runtime autoload/ale/lsp_linter.vim
|
|
|
|
runtime autoload/ale/lsp.vim
|
|
|
|
runtime autoload/ale/util.vim
|
|
|
|
runtime autoload/ale/codefix.vim
|
|
|
|
runtime autoload/ale/code_action.vim
|
|
|
|
|
|
|
|
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
|
|
|
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
|
|
|
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
|
|
|
|
|
|
|
if a:linter.lsp is# 'tsserver'
|
|
|
|
call ale#lsp#MarkConnectionAsTsserver(g:conn_id)
|
|
|
|
endif
|
|
|
|
|
|
|
|
let l:details = {
|
|
|
|
\ 'command': 'foobar',
|
|
|
|
\ 'buffer': a:buffer,
|
|
|
|
\ 'connection_id': g:conn_id,
|
|
|
|
\ 'project_root': '/foo/bar',
|
|
|
|
\}
|
|
|
|
|
|
|
|
let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)}
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#lsp#HasCapability(conn_id, capability) abort
|
|
|
|
let g:capability_checked = a:capability
|
|
|
|
|
|
|
|
return 1
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#lsp#RegisterCallback(conn_id, callback) abort
|
|
|
|
let g:Callback = a:callback
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#lsp#Send(conn_id, message) abort
|
|
|
|
call add(g:message_list, a:message)
|
|
|
|
|
|
|
|
return 42
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#util#Execute(expr) abort
|
|
|
|
call add(g:expr_list, a:expr)
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#code_action#HandleCodeAction(code_action, options) abort
|
|
|
|
let g:handle_code_action_called = 1
|
|
|
|
Assert !get(a:options, 'should_save')
|
|
|
|
call add(g:code_actions, a:code_action)
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
function! ale#util#Input(message, value) abort
|
|
|
|
return '2'
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
After:
|
|
|
|
Restore
|
|
|
|
|
|
|
|
if g:conn_id isnot v:null
|
|
|
|
call ale#lsp#RemoveConnectionWithID(g:conn_id)
|
|
|
|
endif
|
|
|
|
|
|
|
|
call ale#test#RestoreDirectory()
|
|
|
|
call ale#linter#Reset()
|
|
|
|
|
|
|
|
unlet! g:capability_checked
|
|
|
|
unlet! g:InitCallback
|
|
|
|
unlet! g:old_filename
|
|
|
|
unlet! g:conn_id
|
|
|
|
unlet! g:Callback
|
|
|
|
unlet! g:message_list
|
|
|
|
unlet! g:expr_list
|
|
|
|
unlet! b:ale_linters
|
|
|
|
unlet! g:options
|
|
|
|
unlet! g:code_actions
|
|
|
|
unlet! g:handle_code_action_called
|
|
|
|
|
|
|
|
runtime autoload/ale/lsp_linter.vim
|
|
|
|
runtime autoload/ale/lsp.vim
|
|
|
|
runtime autoload/ale/util.vim
|
|
|
|
runtime autoload/ale/codefix.vim
|
|
|
|
runtime autoload/ale/code_action.vim
|
|
|
|
|
|
|
|
Execute(Failed codefix responses should be handled correctly):
|
|
|
|
call ale#codefix#HandleTSServerResponse(
|
|
|
|
\ 1,
|
|
|
|
\ {'command': 'getCodeFixes', 'request_seq': 3}
|
|
|
|
\)
|
|
|
|
AssertEqual g:handle_code_action_called, 0
|
|
|
|
|
|
|
|
Given typescript(Some typescript file):
|
|
|
|
foo
|
2020-11-21 01:18:27 +00:00
|
|
|
somelongerline ()
|
2020-11-14 10:15:17 +00:00
|
|
|
bazxyzxyzxyz
|
|
|
|
|
|
|
|
Execute(getCodeFixes from tsserver should be handled):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1, {
|
|
|
|
\ 'command': 'getCodeFixes',
|
|
|
|
\ 'request_seq': 3,
|
|
|
|
\ 'success': v:true,
|
|
|
|
\ 'type': 'response',
|
|
|
|
\ 'body': [
|
|
|
|
\ {
|
|
|
|
\ 'description': 'Import default "x" from module "./z"',
|
|
|
|
\ 'fixName': 'import',
|
|
|
|
\ 'changes': [
|
|
|
|
\ {
|
|
|
|
\ 'fileName': "/foo/bar/file1.ts",
|
|
|
|
\ 'textChanges': [
|
|
|
|
\ {
|
|
|
|
\ 'end': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ },
|
|
|
|
\ 'newText': 'import x from "./z";^@',
|
|
|
|
\ 'start': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ }
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 1
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ {
|
|
|
|
\ 'description': 'codefix',
|
|
|
|
\ 'changes': [
|
|
|
|
\ {
|
|
|
|
\ 'fileName': "/foo/bar/file1.ts",
|
|
|
|
\ 'textChanges': [
|
|
|
|
\ {
|
|
|
|
\ 'end': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1
|
|
|
|
\ },
|
|
|
|
\ 'newText': 'import x from "./z";^@',
|
|
|
|
\ 'start': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1
|
|
|
|
\ }
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ],
|
|
|
|
\ g:code_actions
|
|
|
|
|
|
|
|
Execute(getCodeFixes from tsserver should be handled with user input if there are more than one action):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1, {
|
|
|
|
\ 'command': 'getCodeFixes',
|
|
|
|
\ 'request_seq': 3,
|
|
|
|
\ 'success': v:true,
|
|
|
|
\ 'type': 'response',
|
|
|
|
\ 'body': [
|
|
|
|
\ {
|
|
|
|
\ 'description': 'Import default "x" from module "./z"',
|
|
|
|
\ 'fixName': 'import',
|
|
|
|
\ 'changes': [
|
|
|
|
\ {
|
|
|
|
\ 'fileName': "/foo/bar/file1.ts",
|
|
|
|
\ 'textChanges': [
|
|
|
|
\ {
|
|
|
|
\ 'end': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ },
|
|
|
|
\ 'newText': 'import x from "./z";^@',
|
|
|
|
\ 'start': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ }
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ },
|
|
|
|
\ {
|
|
|
|
\ 'description': 'Import default "x" from module "./y"',
|
|
|
|
\ 'fixName': 'import',
|
|
|
|
\ 'changes': [
|
|
|
|
\ {
|
|
|
|
\ 'fileName': "/foo/bar/file1.ts",
|
|
|
|
\ 'textChanges': [
|
|
|
|
\ {
|
|
|
|
\ 'end': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ },
|
|
|
|
\ 'newText': 'import x from "./y";^@',
|
|
|
|
\ 'start': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1,
|
|
|
|
\ }
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 1
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ {
|
|
|
|
\ 'description': 'codefix',
|
|
|
|
\ 'changes': [
|
|
|
|
\ {
|
|
|
|
\ 'fileName': "/foo/bar/file1.ts",
|
|
|
|
\ 'textChanges': [
|
|
|
|
\ {
|
|
|
|
\ 'end': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1
|
|
|
|
\ },
|
|
|
|
\ 'newText': 'import x from "./y";^@',
|
|
|
|
\ 'start': {
|
|
|
|
\ 'line': 2,
|
|
|
|
\ 'offset': 1
|
|
|
|
\ }
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ]
|
|
|
|
\ }
|
|
|
|
\ ],
|
|
|
|
\ g:code_actions
|
|
|
|
|
|
|
|
Execute(Prints a tsserver error message when getCodeFixes unsuccessful):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1, {
|
|
|
|
\ 'command': 'getCodeFixes',
|
|
|
|
\ 'request_seq': 3,
|
|
|
|
\ 'success': v:false,
|
|
|
|
\ 'message': 'something is wrong',
|
|
|
|
\})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 0
|
|
|
|
AssertEqual ['echom ''Error while getting code fixes. Reason: something is wrong'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(Does nothing when where are no code fixes):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1, {
|
|
|
|
\ 'command': 'getCodeFixes',
|
|
|
|
\ 'request_seq': 3,
|
|
|
|
\ 'success': v:true,
|
|
|
|
\ 'body': []
|
|
|
|
\})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 0
|
|
|
|
AssertEqual ['echom ''No code fixes available.'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(tsserver codefix requests should be sent):
|
|
|
|
call ale#linter#Reset()
|
|
|
|
|
|
|
|
runtime ale_linters/typescript/tsserver.vim
|
2021-09-16 13:05:38 +00:00
|
|
|
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304, 'linter_name': 'tsserver'}]}}
|
2020-11-21 01:18:27 +00:00
|
|
|
call setpos('.', [bufnr(''), 2, 16, 0])
|
2020-11-14 10:15:17 +00:00
|
|
|
|
|
|
|
" ALECodeAction
|
|
|
|
call ale#codefix#Execute(0)
|
|
|
|
|
|
|
|
" We shouldn't register the callback yet.
|
|
|
|
AssertEqual '''''', string(g:Callback)
|
|
|
|
|
|
|
|
AssertEqual type(function('type')), type(g:InitCallback)
|
|
|
|
call g:InitCallback()
|
|
|
|
|
|
|
|
AssertEqual 'code_actions', g:capability_checked
|
|
|
|
AssertEqual
|
|
|
|
\ 'function(''ale#codefix#HandleTSServerResponse'')',
|
|
|
|
\ string(g:Callback)
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ ale#lsp#tsserver_message#Change(bufnr('')),
|
|
|
|
\ [0, 'ts@getCodeFixes', {
|
|
|
|
\ 'startLine': 2,
|
2020-11-21 01:18:27 +00:00
|
|
|
\ 'startOffset': 16,
|
2020-11-14 10:15:17 +00:00
|
|
|
\ 'endLine': 2,
|
2020-11-21 01:18:27 +00:00
|
|
|
\ 'endOffset': 17,
|
2020-11-14 10:15:17 +00:00
|
|
|
\ 'file': expand('%:p'),
|
|
|
|
\ 'errorCodes': [2304],
|
|
|
|
\ }]
|
|
|
|
\ ],
|
|
|
|
\ g:message_list
|
|
|
|
|
|
|
|
Execute(tsserver codefix requests should be sent only for error with code):
|
|
|
|
call ale#linter#Reset()
|
|
|
|
|
|
|
|
runtime ale_linters/typescript/tsserver.vim
|
2021-09-16 13:05:38 +00:00
|
|
|
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 16, 'linter_name': 'tsserver'}, {'lnum': 2, 'col': 16, 'code': 2304, 'linter_name': 'tsserver'}]}}
|
2020-11-21 01:18:27 +00:00
|
|
|
call setpos('.', [bufnr(''), 2, 16, 0])
|
2020-11-14 10:15:17 +00:00
|
|
|
|
|
|
|
" ALECodeAction
|
|
|
|
call ale#codefix#Execute(0)
|
|
|
|
|
|
|
|
" We shouldn't register the callback yet.
|
|
|
|
AssertEqual '''''', string(g:Callback)
|
|
|
|
|
|
|
|
AssertEqual type(function('type')), type(g:InitCallback)
|
|
|
|
call g:InitCallback()
|
|
|
|
|
|
|
|
AssertEqual 'code_actions', g:capability_checked
|
|
|
|
AssertEqual
|
|
|
|
\ 'function(''ale#codefix#HandleTSServerResponse'')',
|
|
|
|
\ string(g:Callback)
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ ale#lsp#tsserver_message#Change(bufnr('')),
|
|
|
|
\ [0, 'ts@getCodeFixes', {
|
|
|
|
\ 'startLine': 2,
|
2020-11-21 01:18:27 +00:00
|
|
|
\ 'startOffset': 16,
|
2020-11-14 10:15:17 +00:00
|
|
|
\ 'endLine': 2,
|
2020-11-21 01:18:27 +00:00
|
|
|
\ 'endOffset': 17,
|
2020-11-14 10:15:17 +00:00
|
|
|
\ 'file': expand('%:p'),
|
|
|
|
\ 'errorCodes': [2304],
|
|
|
|
\ }]
|
|
|
|
\ ],
|
|
|
|
\ g:message_list
|
|
|
|
|
|
|
|
Execute(getApplicableRefactors from tsserver should be handled):
|
|
|
|
call ale#codefix#SetMap({3: {
|
|
|
|
\ 'buffer': expand('%:p'),
|
|
|
|
\ 'line': 1,
|
|
|
|
\ 'column': 2,
|
|
|
|
\ 'end_line': 3,
|
|
|
|
\ 'end_column': 4,
|
|
|
|
\ 'connection_id': 0,
|
|
|
|
\}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1,
|
|
|
|
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [{'actions': [{'description': 'Extract to constant in enclosing scope', 'name': 'constant_scope_0'}], 'description': 'Extract constant', 'name': 'Extract Symbol'}, {'actions': [{'description': 'Extract to function in module scope', 'name': 'function_scope_1'}], 'description': 'Extract function', 'name': 'Extract Symbol'}], 'command': 'getApplicableRefactors'})
|
|
|
|
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ [0, 'ts@getEditsForRefactor', {
|
|
|
|
\ 'startLine': 1,
|
|
|
|
\ 'startOffset': 2,
|
|
|
|
\ 'endLine': 3,
|
|
|
|
\ 'endOffset': 5,
|
|
|
|
\ 'file': expand('%:p'),
|
|
|
|
\ 'refactor': 'Extract Symbol',
|
|
|
|
\ 'action': 'function_scope_1',
|
|
|
|
\ }]
|
|
|
|
\ ],
|
|
|
|
\ g:message_list
|
|
|
|
|
|
|
|
Execute(getApplicableRefactors should print error on failure):
|
|
|
|
call ale#codefix#SetMap({3: {
|
|
|
|
\ 'buffer': expand('%:p'),
|
|
|
|
\ 'line': 1,
|
|
|
|
\ 'column': 2,
|
|
|
|
\ 'end_line': 3,
|
|
|
|
\ 'end_column': 4,
|
|
|
|
\ 'connection_id': 0,
|
|
|
|
\}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1,
|
|
|
|
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getApplicableRefactors'})
|
|
|
|
|
|
|
|
AssertEqual ['echom ''Error while getting applicable refactors. Reason: oops'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(getApplicableRefactors should do nothing if there are no refactors):
|
|
|
|
call ale#codefix#SetMap({3: {
|
|
|
|
\ 'buffer': expand('%:p'),
|
|
|
|
\ 'line': 1,
|
|
|
|
\ 'column': 2,
|
|
|
|
\ 'end_line': 3,
|
|
|
|
\ 'end_column': 4,
|
|
|
|
\ 'connection_id': 0,
|
|
|
|
\}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1,
|
|
|
|
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [], 'command': 'getApplicableRefactors'})
|
|
|
|
|
|
|
|
AssertEqual ['echom ''No applicable refactors available.'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(getEditsForRefactor from tsserver should be handled):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1,
|
|
|
|
\{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': {'edits': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], 'renameLocation': {'offset': 3, 'line': 8}, 'renameFilename': '/foo/bar/file.ts'}, 'command': 'getEditsForRefactor' }
|
|
|
|
\)
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 1
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ {
|
|
|
|
\ 'description': 'editsForRefactor',
|
|
|
|
\ 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}],
|
|
|
|
\ }
|
|
|
|
\ ],
|
|
|
|
\ g:code_actions
|
|
|
|
|
|
|
|
Execute(getEditsForRefactor should print error on failure):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleTSServerResponse(1,
|
|
|
|
\{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getEditsForRefactor' }
|
|
|
|
\)
|
|
|
|
|
|
|
|
AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(Failed LSP responses should be handled correctly):
|
|
|
|
call ale#codefix#HandleLSPResponse(
|
|
|
|
\ 1,
|
|
|
|
\ {'method': 'workspace/applyEdit', 'request_seq': 3}
|
|
|
|
\)
|
|
|
|
AssertEqual g:handle_code_action_called, 0
|
|
|
|
|
|
|
|
Given python(Some python file):
|
|
|
|
def main():
|
|
|
|
a = 1
|
|
|
|
b = a + 2
|
|
|
|
|
|
|
|
Execute("workspace/applyEdit" from LSP should be handled):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleLSPResponse(1,
|
|
|
|
\ {'id': 0, 'jsonrpc': '2.0', 'method': 'workspace/applyEdit', 'params': {'edit': {'changes': {'file:///foo/bar/file.ts': [{'range': {'end': {'character': 27, 'line': 7}, 'start': {'character': 27, 'line': 7}}, 'newText': ', Config'}, {'range': {'end': {'character': 12, 'line': 96}, 'start': {'character': 2, 'line': 94}}, 'newText': 'await newFunction(redis, imageKey, cover, config);'}, {'range': {'end': {'character': 2, 'line': 99}, 'start': {'character': 2, 'line': 99}}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@'}]}}}})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 1
|
|
|
|
AssertEqual
|
|
|
|
\ [{'description': 'applyEdit', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 28, 'line': 8}, 'newText': ', Config', 'start': {'offset': 28, 'line': 8}}, {'end': {'offset': 13, 'line': 97}, 'newText': 'await newFunction(redis, imageKey, cover, config);', 'start': {'offset': 3, 'line': 95}}, {'end': {'offset': 3, 'line': 100}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@', 'start': {'offset': 3, 'line': 100}}]}]}],
|
|
|
|
\ g:code_actions
|
|
|
|
|
|
|
|
Execute(Code Actions from LSP should be handled when returned with documentChanges):
|
|
|
|
call ale#codefix#SetMap({2: {}})
|
|
|
|
call ale#codefix#HandleLSPResponse(1,
|
|
|
|
\ {'id': 2, 'jsonrpc': '2.0', 'result': [{'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 1}}, 'newText': ''}, {'range': {'end': {'character': 9, 'line': 2}, 'start': {'character': 8, 'line': 2}}, 'newText': '(1)'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.inline', 'title': 'Inline variable', 'command': v:null}, {'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 0, 'line': 0}, 'start': {'character': 0, 'line': 0}}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@'}, {'range': {'end': {'character': 9, 'line': 1}, 'start': {'character': 8, 'line': 1}}, 'newText': 'func_bomdjnxh()^@'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.extract', 'title': 'Extract expression into function ''func_bomdjnxh''', 'command': v:null}]})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 1
|
|
|
|
AssertEqual
|
|
|
|
\ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/test.py', 'textChanges': [{'end': {'offset': 1, 'line': 1}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@', 'start': {'offset': 1, 'line': 1}}, {'end': {'offset': 10, 'line': 2}, 'newText': 'func_bomdjnxh()^@', 'start': {'offset': 9, 'line': 2}}]}]}],
|
|
|
|
\ g:code_actions
|
|
|
|
|
2021-10-07 02:29:00 +00:00
|
|
|
Execute(LSP Code Actions handles CodeAction responses):
|
2020-11-14 10:15:17 +00:00
|
|
|
call ale#codefix#SetMap({3: {
|
|
|
|
\ 'connection_id': 0,
|
|
|
|
\}})
|
|
|
|
call ale#codefix#HandleLSPResponse(1,
|
|
|
|
\ {'id': 3, 'jsonrpc': '2.0', 'result': [{'kind': 'refactor', 'title': 'Extract to inner function in function ''getVideo''', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_0', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to inner function in function ''getVideo''', 'command': '_typescript.applyRefactoring'}}, {'kind': 'refactor', 'title': 'Extract to function in module scope', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_1', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to function in module scope', 'command': '_typescript.applyRefactoring'}}]})
|
|
|
|
|
|
|
|
AssertEqual
|
|
|
|
\ [[0, 'workspace/executeCommand', {'arguments': [{'file': '/foo/bar/file.ts', 'action': 'function_scope_1', 'endOffset': 0, 'refactor': 'Extract Symbol', 'endLine': 68, 'startLine': 65, 'startOffset': 1}], 'command': '_typescript.applyRefactoring'}]],
|
|
|
|
\ g:message_list
|
|
|
|
|
2021-10-07 02:29:00 +00:00
|
|
|
Execute(LSP Code Actions handles Command responses):
|
|
|
|
call ale#codefix#SetMap({2: {
|
|
|
|
\ 'connection_id': 2,
|
|
|
|
\}})
|
|
|
|
call ale#codefix#HandleLSPResponse(1,
|
|
|
|
\ {'id': 2, 'jsonrpc': '2.0', 'result': [{'title': 'fake for testing'}, {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'title': 'Add ''createVideo'' to existing import declaration from "./video"', 'command': '_typescript.applyWorkspaceEdit'}]})
|
|
|
|
|
|
|
|
AssertEqual
|
|
|
|
\ [[0, 'workspace/executeCommand', {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'command': '_typescript.applyWorkspaceEdit'}]],
|
|
|
|
\ g:message_list
|
2020-11-14 10:15:17 +00:00
|
|
|
|
|
|
|
Execute(Prints message when LSP code action returns no results):
|
|
|
|
call ale#codefix#SetMap({3: {}})
|
|
|
|
call ale#codefix#HandleLSPResponse(1,
|
|
|
|
\ {'id': 3, 'jsonrpc': '2.0', 'result': []})
|
|
|
|
|
|
|
|
AssertEqual g:handle_code_action_called, 0
|
|
|
|
AssertEqual ['echom ''No code actions received from server'''], g:expr_list
|
|
|
|
|
|
|
|
Execute(LSP code action requests should be sent):
|
|
|
|
call ale#linter#Reset()
|
|
|
|
|
|
|
|
runtime ale_linters/python/jedils.vim
|
|
|
|
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
|
|
|
|
call setpos('.', [bufnr(''), 2, 5, 0])
|
|
|
|
|
|
|
|
" ALECodeAction
|
|
|
|
call ale#codefix#Execute(0)
|
|
|
|
|
|
|
|
" We shouldn't register the callback yet.
|
|
|
|
AssertEqual '''''', string(g:Callback)
|
|
|
|
|
|
|
|
AssertEqual type(function('type')), type(g:InitCallback)
|
|
|
|
call g:InitCallback()
|
|
|
|
|
|
|
|
AssertEqual 'code_actions', g:capability_checked
|
|
|
|
AssertEqual
|
|
|
|
\ 'function(''ale#codefix#HandleLSPResponse'')',
|
|
|
|
\ string(g:Callback)
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ [0, 'textDocument/codeAction', {
|
|
|
|
\ 'context': {
|
2020-11-21 01:26:16 +00:00
|
|
|
\ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
|
2020-11-14 10:15:17 +00:00
|
|
|
\ },
|
|
|
|
\ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
|
2022-03-04 19:03:27 +00:00
|
|
|
\ 'textDocument': {'uri': ale#path#ToFileURI(expand('%:p'))}
|
2020-11-14 10:15:17 +00:00
|
|
|
\ }]
|
|
|
|
\ ],
|
2020-11-21 01:18:27 +00:00
|
|
|
\ g:message_list[-1:]
|
2020-11-14 10:15:17 +00:00
|
|
|
|
|
|
|
Execute(LSP code action requests should be sent only for error with code):
|
|
|
|
call ale#linter#Reset()
|
|
|
|
|
|
|
|
runtime ale_linters/python/jedils.vim
|
|
|
|
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
|
|
|
|
call setpos('.', [bufnr(''), 2, 5, 0])
|
|
|
|
|
|
|
|
" ALECodeAction
|
|
|
|
call ale#codefix#Execute(0)
|
|
|
|
|
|
|
|
" We shouldn't register the callback yet.
|
|
|
|
AssertEqual '''''', string(g:Callback)
|
|
|
|
|
|
|
|
AssertEqual type(function('type')), type(g:InitCallback)
|
|
|
|
call g:InitCallback()
|
|
|
|
|
|
|
|
AssertEqual 'code_actions', g:capability_checked
|
|
|
|
AssertEqual
|
|
|
|
\ 'function(''ale#codefix#HandleLSPResponse'')',
|
|
|
|
\ string(g:Callback)
|
|
|
|
AssertEqual
|
|
|
|
\ [
|
|
|
|
\ [0, 'textDocument/codeAction', {
|
|
|
|
\ 'context': {
|
2020-11-21 01:26:16 +00:00
|
|
|
\ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
|
2020-11-14 10:15:17 +00:00
|
|
|
\ },
|
|
|
|
\ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
|
2022-03-04 19:03:27 +00:00
|
|
|
\ 'textDocument': {'uri': ale#path#ToFileURI(expand('%:p'))}
|
2020-11-14 10:15:17 +00:00
|
|
|
\ }]
|
|
|
|
\ ],
|
2020-11-21 01:18:27 +00:00
|
|
|
\ g:message_list[-1:]
|