2019-11-24 04:01:18 -07:00
local vim = vim
2019-11-20 15:21:57 -07:00
local validate = vim.validate
local api = vim.api
2019-11-20 16:35:18 -07:00
local vfn = vim.fn
2019-11-20 15:21:57 -07:00
local util = require ' vim.lsp.util '
2019-11-21 17:23:12 -07:00
local list_extend = vim.list_extend
2019-11-20 15:21:57 -07:00
local M = { }
local function ok_or_nil ( status , ... )
2019-11-20 17:16:36 -07:00
if not status then return end
return ...
2019-11-20 15:21:57 -07:00
end
local function npcall ( fn , ... )
2019-11-20 17:16:36 -07:00
return ok_or_nil ( pcall ( fn , ... ) )
2019-11-20 15:21:57 -07:00
end
2019-11-20 16:35:18 -07:00
local function request ( method , params , callback )
2019-11-20 17:16:36 -07:00
validate {
method = { method , ' s ' } ;
2019-11-26 06:59:40 -07:00
callback = { callback , ' f ' , true } ;
2019-11-20 17:16:36 -07:00
}
2019-11-26 06:59:40 -07:00
return vim.lsp . buf_request ( 0 , method , params , callback )
2019-11-20 16:35:18 -07:00
end
function M . hover ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/hover ' , params )
2019-11-20 15:21:57 -07:00
end
2019-11-20 16:35:18 -07:00
function M . peek_definition ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/peekDefinition ' , params )
2019-11-20 16:35:18 -07:00
end
2019-11-20 15:21:57 -07:00
function M . declaration ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/declaration ' , params )
2019-11-20 16:35:18 -07:00
end
function M . definition ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/definition ' , params )
2019-11-20 15:21:57 -07:00
end
function M . type_definition ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/typeDefinition ' , params )
2019-11-20 15:21:57 -07:00
end
function M . implementation ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/implementation ' , params )
2019-11-20 17:03:32 -07:00
end
2019-11-20 16:35:18 -07:00
function M . signature_help ( )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-26 06:59:40 -07:00
request ( ' textDocument/signatureHelp ' , params )
2019-11-20 15:21:57 -07:00
end
-- TODO(ashkan) ?
2019-11-20 16:35:18 -07:00
function M . completion ( context )
2019-11-21 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-20 17:16:36 -07:00
params.context = context
2019-11-26 06:59:40 -07:00
return request ( ' textDocument/completion ' , params )
2019-11-20 15:21:57 -07:00
end
2019-11-20 21:51:44 -07:00
function M . formatting ( options )
validate { options = { options , ' t ' , true } }
2019-11-21 16:19:06 -07:00
options = vim.tbl_extend ( ' keep ' , options or { } , {
2019-11-26 06:59:40 -07:00
tabSize = vim.bo . tabstop ;
insertSpaces = vim.bo . expandtab ;
2019-11-21 16:19:06 -07:00
} )
2019-11-20 21:51:44 -07:00
local params = {
textDocument = { uri = vim.uri_from_bufnr ( 0 ) } ;
2019-11-21 16:19:06 -07:00
options = options ;
2019-11-20 21:51:44 -07:00
}
2019-11-26 06:59:40 -07:00
return request ( ' textDocument/formatting ' , params )
2019-11-20 21:51:44 -07: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 } ;
}
2019-11-21 16:19:06 -07:00
options = vim.tbl_extend ( ' keep ' , options or { } , {
2019-11-26 06:59:40 -07:00
tabSize = vim.bo . tabstop ;
insertSpaces = vim.bo . expandtab ;
2019-11-21 16:19:06 -07:00
} )
2019-11-21 17:23:12 -07: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 06:59:40 -07:00
A = { A [ 1 ] , util.character_offset ( 0 , A [ 1 ] , A [ 2 ] ) }
2019-11-21 17:23:12 -07:00
end
if B [ 2 ] > 0 then
2019-11-26 06:59:40 -07:00
B = { B [ 1 ] , util.character_offset ( 0 , B [ 1 ] , B [ 2 ] ) }
2019-11-21 17:23:12 -07:00
end
2019-11-20 21:51:44 -07:00
local params = {
textDocument = { uri = vim.uri_from_bufnr ( 0 ) } ;
range = {
2019-11-21 17:23:12 -07:00
start = { line = A [ 1 ] ; character = A [ 2 ] ; } ;
[ " end " ] = { line = B [ 1 ] ; character = B [ 2 ] ; } ;
2019-11-20 21:51:44 -07:00
} ;
2019-11-21 16:19:06 -07:00
options = options ;
2019-11-20 21:51:44 -07:00
}
2019-11-26 06:59:40 -07:00
return request ( ' textDocument/rangeFormatting ' , params )
2019-11-20 15:21:57 -07:00
end
2019-11-20 17:03:32 -07:00
function M . rename ( new_name )
2019-11-20 17:16:36 -07: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 16:41:32 -07:00
local params = util.make_position_params ( )
2019-11-20 17:16:36 -07: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 06:59:40 -07:00
request ( ' textDocument/rename ' , params )
2019-11-20 17:03:32 -07:00
end
2019-11-24 04:01:18 -07: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 06:59:40 -07:00
request ( ' textDocument/references ' , params )
2019-11-24 04:01:18 -07:00
end
2019-11-20 15:21:57 -07:00
return M
2019-11-20 17:16:36 -07:00
-- vim:sw=2 ts=2 et