2019-11-24 03:01:18 -08:00
local vim = vim
2019-11-20 14:21:57 -08:00
local validate = vim.validate
local api = vim.api
2019-11-20 15:35:18 -08:00
local vfn = vim.fn
2019-11-20 14:21:57 -08:00
local util = require ' vim.lsp.util '
2019-11-21 16:23:12 -08:00
local list_extend = vim.list_extend
2019-11-20 14:21:57 -08:00
local M = { }
local function ok_or_nil ( status , ... )
2019-11-20 16:16:36 -08:00
if not status then return end
return ...
2019-11-20 14:21:57 -08:00
end
local function npcall ( fn , ... )
2019-11-20 16:16:36 -08:00
return ok_or_nil ( pcall ( fn , ... ) )
2019-11-20 14:21:57 -08:00
end
2019-11-20 15:35:18 -08:00
local function request ( method , params , callback )
2019-11-20 16:16:36 -08:00
validate {
method = { method , ' s ' } ;
2019-11-26 05:59:40 -08:00
callback = { callback , ' f ' , true } ;
2019-11-20 16:16:36 -08:00
}
2019-11-26 05:59:40 -08:00
return vim.lsp . buf_request ( 0 , method , params , callback )
2019-11-20 15:35:18 -08:00
end
2020-02-26 20:22:14 +01:00
function M . server_ready ( )
return not not vim.lsp . buf_notify ( 0 , " window/progress " , { } )
end
2019-11-20 15:35:18 -08:00
function M . hover ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/hover ' , params )
2019-11-20 14:21:57 -08:00
end
2019-11-20 15:35:18 -08:00
function M . peek_definition ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/peekDefinition ' , params )
2019-11-20 15:35:18 -08:00
end
2019-11-20 14:21:57 -08:00
function M . declaration ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/declaration ' , params )
2019-11-20 15:35:18 -08:00
end
function M . definition ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/definition ' , params )
2019-11-20 14:21:57 -08:00
end
function M . type_definition ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/typeDefinition ' , params )
2019-11-20 14:21:57 -08:00
end
function M . implementation ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/implementation ' , params )
2019-11-20 16:03:32 -08:00
end
2019-11-20 15:35:18 -08:00
function M . signature_help ( )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-26 05:59:40 -08:00
request ( ' textDocument/signatureHelp ' , params )
2019-11-20 14:21:57 -08:00
end
-- TODO(ashkan) ?
2019-11-20 15:35:18 -08:00
function M . completion ( context )
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-20 16:16:36 -08:00
params.context = context
2019-11-26 05:59:40 -08:00
return request ( ' textDocument/completion ' , params )
2019-11-20 14:21:57 -08:00
end
2019-11-20 20:51:44 -08:00
function M . formatting ( options )
validate { options = { options , ' t ' , true } }
2020-02-11 07:53:14 +01:00
local sts = vim.bo . softtabstop ;
2019-11-21 15:19:06 -08:00
options = vim.tbl_extend ( ' keep ' , options or { } , {
2020-02-11 07:53:14 +01:00
tabSize = ( sts > 0 and sts ) or ( sts < 0 and vim.bo . shiftwidth ) or vim.bo . tabstop ;
2019-11-26 05:59:40 -08:00
insertSpaces = vim.bo . expandtab ;
2019-11-21 15:19:06 -08:00
} )
2019-11-20 20:51:44 -08:00
local params = {
textDocument = { uri = vim.uri_from_bufnr ( 0 ) } ;
2019-11-21 15:19:06 -08:00
options = options ;
2019-11-20 20:51:44 -08:00
}
2019-11-26 05:59:40 -08:00
return request ( ' textDocument/formatting ' , params )
2019-11-20 20:51:44 -08:00
end
function M . range_formatting ( options , start_pos , end_pos )
validate {
options = { options , ' t ' , true } ;
start_pos = { start_pos , ' t ' , true } ;
end_pos = { end_pos , ' t ' , true } ;
}
2020-02-11 07:53:14 +01:00
local sts = vim.bo . softtabstop ;
2019-11-21 15:19:06 -08:00
options = vim.tbl_extend ( ' keep ' , options or { } , {
2020-02-11 07:53:14 +01:00
tabSize = ( sts > 0 and sts ) or ( sts < 0 and vim.bo . shiftwidth ) or vim.bo . tabstop ;
2019-11-26 05:59:40 -08:00
insertSpaces = vim.bo . expandtab ;
2019-11-21 15:19:06 -08:00
} )
2019-11-21 16:23:12 -08:00
local A = list_extend ( { } , start_pos or api.nvim_buf_get_mark ( 0 , ' < ' ) )
local B = list_extend ( { } , end_pos or api.nvim_buf_get_mark ( 0 , ' > ' ) )
-- convert to 0-index
A [ 1 ] = A [ 1 ] - 1
B [ 1 ] = B [ 1 ] - 1
-- account for encoding.
if A [ 2 ] > 0 then
2019-11-26 05:59:40 -08:00
A = { A [ 1 ] , util.character_offset ( 0 , A [ 1 ] , A [ 2 ] ) }
2019-11-21 16:23:12 -08:00
end
if B [ 2 ] > 0 then
2019-11-26 05:59:40 -08:00
B = { B [ 1 ] , util.character_offset ( 0 , B [ 1 ] , B [ 2 ] ) }
2019-11-21 16:23:12 -08:00
end
2019-11-20 20:51:44 -08:00
local params = {
textDocument = { uri = vim.uri_from_bufnr ( 0 ) } ;
range = {
2019-11-21 16:23:12 -08:00
start = { line = A [ 1 ] ; character = A [ 2 ] ; } ;
[ " end " ] = { line = B [ 1 ] ; character = B [ 2 ] ; } ;
2019-11-20 20:51:44 -08:00
} ;
2019-11-21 15:19:06 -08:00
options = options ;
2019-11-20 20:51:44 -08:00
}
2019-11-26 05:59:40 -08:00
return request ( ' textDocument/rangeFormatting ' , params )
2019-11-20 14:21:57 -08:00
end
2019-11-20 16:03:32 -08:00
function M . rename ( new_name )
2019-11-20 16:16:36 -08:00
-- TODO(ashkan) use prepareRename
-- * result: [`Range`](#range) \| `{ range: Range, placeholder: string }` \| `null` describing the range of the string to rename and optionally a placeholder text of the string content to be renamed. If `null` is returned then it is deemed that a 'textDocument/rename' request is not valid at the given position.
2019-11-21 15:41:32 -08:00
local params = util.make_position_params ( )
2019-11-20 16:16:36 -08:00
new_name = new_name or npcall ( vfn.input , " New Name: " )
if not ( new_name and # new_name > 0 ) then return end
params.newName = new_name
2019-11-26 05:59:40 -08:00
request ( ' textDocument/rename ' , params )
2019-11-20 16:03:32 -08:00
end
2019-11-24 03:01:18 -08:00
function M . references ( context )
validate { context = { context , ' t ' , true } }
local params = util.make_position_params ( )
params.context = context or {
includeDeclaration = true ;
}
params [ vim.type_idx ] = vim.types . dictionary
2019-11-26 05:59:40 -08:00
request ( ' textDocument/references ' , params )
2019-11-24 03:01:18 -08:00
end
2020-02-26 20:10:16 +01:00
--- Send request to server to resolve document highlights for the
--- current text document position. This request can be associated
--- to key mapping or to events such as `CursorHold`, eg:
---
--- <pre>
--- vim.api.nvim_command [[autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()]]
--- vim.api.nvim_command [[autocmd CursorHoldI <buffer> lua vim.lsp.buf.document_highlight()]]
--- vim.api.nvim_command [[autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()]]
--- </pre>
function M . document_highlight ( )
local params = util.make_position_params ( )
request ( ' textDocument/documentHighlight ' , params )
end
function M . clear_references ( )
util.buf_clear_references ( )
end
2019-11-20 14:21:57 -08:00
return M
2019-11-20 16:16:36 -08:00
-- vim:sw=2 ts=2 et