From 9eb9c8d576da0062ce324a5d2982f98ec3c5510a Mon Sep 17 00:00:00 2001 From: TJ DeVries Date: Fri, 18 Nov 2016 15:18:57 -0500 Subject: [PATCH] Start working on ability for server to send commands --- autoload/langserver/callbacks.vim | 68 ++++++++++++++--------- autoload/langserver/client.vim | 18 +++++- autoload/langserver/extension/command.vim | 29 ++++++++++ autoload/langserver/extension/fs.vim | 11 ++++ autoload/langserver/log.vim | 11 ++++ 5 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 autoload/langserver/extension/command.vim create mode 100644 autoload/langserver/extension/fs.vim diff --git a/autoload/langserver/callbacks.vim b/autoload/langserver/callbacks.vim index cb5f2c4..d09aae7 100644 --- a/autoload/langserver/callbacks.vim +++ b/autoload/langserver/callbacks.vim @@ -3,7 +3,11 @@ function! langserver#callbacks#on_stdout(id, data, event) abort endfunction function! langserver#callbacks#on_stderr(id, data, event) abort + echom 'stderr ...' call langserver#log#response(a:id, a:data, a:event) + + echom string(a:data) + echom '...stderr' endfunction function! langserver#callbacks#on_exit(id, status, event) abort @@ -11,37 +15,47 @@ function! langserver#callbacks#on_exit(id, status, event) abort endfunction function! langserver#callbacks#on_notification(id, data, event) abort + if a:event ==? 'on_request' + call langserver#extension#command#callback(a:id, a:data, a:event) + elseif a:event ==? 'on_notification' + if has_key(a:data, 'response') + call langserver#log#response(a:id, a:data, a:event) - if has_key(a:data, 'response') - call langserver#log#response(a:id, a:data, a:event) - - let l:last_topic = a:data['request']['method'] + let l:last_topic = a:data['request']['method'] - if l:last_topic ==? 'textDocument/references' - call langserver#references#callback(a:id, a:data, a:event) - elseif l:last_topic ==? 'textDocument/definition' - call langserver#goto#callback(a:id, a:data, a:event) - elseif l:last_topic ==? 'textDocument/hover' - call langserver#hover#callback(a:id, a:data, a:event) - elseif l:last_topic ==? 'textDocument/didOpen' - call langserver#documents#callback_did_open(a:id, a:data, a:event) - elseif l:last_topic ==? 'workspace/symbol' - call langserver#symbol#workspace#callback(a:id, a:data, a:event) - else - call langserver#log#log('warning', 'LAST REQUEST: ' . l:last_topic, v:true) + if l:last_topic ==? 'textDocument/references' + call langserver#references#callback(a:id, a:data, a:event) + elseif l:last_topic ==? 'textDocument/definition' + call langserver#goto#callback(a:id, a:data, a:event) + elseif l:last_topic ==? 'textDocument/hover' + call langserver#hover#callback(a:id, a:data, a:event) + elseif l:last_topic ==? 'textDocument/didOpen' + call langserver#documents#callback_did_open(a:id, a:data, a:event) + elseif l:last_topic ==? 'workspace/symbol' + call langserver#symbol#workspace#callback(a:id, a:data, a:event) + else + " if langserver#extension#command#callback(a:id, a:data, a:event) + " call langserver#log#log('debug', 'Handled: ' . l:last_topic) + " else + call langserver#log#log('warning', 'LAST REQUEST: ' . l:last_topic, v:true) + " endif + endif + elseif has_key(a:data, 'request') + echom 'notification...' + echom string(a:data) + echom '...notification' endif - endif - if langserver#client#is_error(a:data.response) - echom 'lsp('.a:id.'):notification:notification error receieved for '.a:data.request.method - else - if langserver#util#debug() - " echom 'lsp('.a:id.'):notification:notification success receieved for '.a:data.request.method - endif - - if a:data.request.method ==? 'textDocument/references' - echom 'LSP NOTIFI References Method matched: ' . string(a:data.request) - " call langserver#references#callback(a:data.request) + if langserver#client#is_error(a:data.response) + call langserver#log#log('debug', + \ 'lsp('.a:id.'):notification:notification error receieved for '.a:data.request.method, + \ v:true, + \ ) + else + call langserver#log#log('debug', + \ 'lsp('.a:id.'):notification:notification success receieved for '.a:data.request.method, + \ langserver#util#debug(), + \ ) endif endif endfunction diff --git a/autoload/langserver/client.vim b/autoload/langserver/client.vim index eff84e7..a6e3371 100644 --- a/autoload/langserver/client.vim +++ b/autoload/langserver/client.vim @@ -60,6 +60,12 @@ function! s:_on_lsp_stdout(id, data, event) abort call l:client.on_notifications[l:response_msg.id](a:id, l:on_notification_data, 'on_notification') endif call remove(l:client.on_notifications, l:response_msg.id) + else + echom string(l:client) + let l:on_notification_data = { + \ 'request': l:response_msg, + \ } + call l:client.opts.on_notification(a:id, l:on_notification_data, 'on_request') endif continue else @@ -128,8 +134,12 @@ function! s:lsp_send_request(id, opts) abort " opts = { method, params?, on_noti if has_key(s:lsp_clients, a:id) let l:client = s:lsp_clients[a:id] - let l:client.req_seq = l:client.req_seq + 1 - let l:req_seq = l:client.req_seq + if has_key(a:opts, 'req_id') + let l:req_seq = a:opts.req_id + else + let l:client.req_seq = l:client.req_seq + 1 + let l:req_seq = l:client.req_seq + endif let l:msg = { 'jsonrpc': '2.0', 'id': l:req_seq, 'method': a:opts.method } if has_key(a:opts, 'params') @@ -148,6 +158,10 @@ function! s:lsp_send_request(id, opts) abort " opts = { method, params?, on_noti let l:client.opts.on_stderr = a:opts.on_stderr endif + call langserver#log#log('debug', printf('Sending request: %s, %s', + \ a:id, + \ string(l:msg) + \ )) call langserver#job#send(l:client.id, l:req_data) return l:req_seq diff --git a/autoload/langserver/extension/command.vim b/autoload/langserver/extension/command.vim new file mode 100644 index 0000000..bed1fe1 --- /dev/null +++ b/autoload/langserver/extension/command.vim @@ -0,0 +1,29 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Command handler +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! langserver#extension#command#callback(id, data, event) abort + call langserver#log#server_request(a:id, a:data, a:event) + + if type(a:data) != type({}) + return + endif + + let l:method = a:data.request.method + + if l:method ==? 'fs/readFile' + let l:response = langserver#extension#fs#readFille(a:data.request.params) + else + call langserver#log#log('warning', 'No matching callback found for: ' . l:method) + return v:false + endif + + call langserver#client#send(a:id, { + \ 'req_id': a:data.request.id, + \ 'method': 'fs/readFile', + \ 'params': { + \ 'result': l:response, + \ }, + \ }) + return v:true +endfunction diff --git a/autoload/langserver/extension/fs.vim b/autoload/langserver/extension/fs.vim new file mode 100644 index 0000000..adf4ae6 --- /dev/null +++ b/autoload/langserver/extension/fs.vim @@ -0,0 +1,11 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Extension to handle "fl/#" commands +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +"" +" Respond with the full file reading +function! langserver#extension#fs#readFille(filename) abort + echom a:filename + + return join(readfile(a:filename), "\n") +endfunction diff --git a/autoload/langserver/log.vim b/autoload/langserver/log.vim index d512189..26186e3 100644 --- a/autoload/langserver/log.vim +++ b/autoload/langserver/log.vim @@ -115,6 +115,17 @@ function! langserver#log#callback(id, data, event) abort \)) endfunction +"" +" Log a request from the server +function! langserver#log#server_request(id, data, event) abort + call langserver#log#log('info', + \ printf('(%3s:%15s): %s', + \ a:id, + \ a:event, + \ string(a:data) + \ )) +endfunction + function! langserver#log#pretty_print(json_dict) abort " TODO: Get pretty printing of json dictionaries if possible let g:my_var = system([