Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upLSP final candidate #11336
LSP final candidate #11336
Conversation
Language Server Protocol defines two message types which are Request Message and Notification Message from client. Now, built-in lsp client is implemented only Request Message. So I impletent Notification Message.
I want to let lsp lib simplify at first. So I remove pre and post autocmd hook until needed them.
…ntation
Now, we provide builtin callbacks instead of default callbacks. So I remove default property from CallbakcObject
`table ~= {}` always returns false. And I think is_empty function should be for table, so if is_empty receive another type instead of table, it throws error. I think `next(table)` is better way that check whether table is empty or not.
…type callbacks.
I think client complex more than necessary. So I remove autocmds module until we really need.
for i = 1, #line_diags - 1 do | ||
table.insert(virt_texts, {"■", severity_highlights[line_diags[i].severity]}) | ||
end | ||
local last = line_diags[#line_diags] |
This comment has been minimized.
This comment has been minimized.
bfredl
Nov 13, 2019
Member
is the spec guaranteeing that a diagnostic with highest severity comes last? (just wondering, we can improve this later)
This comment has been minimized.
This comment has been minimized.
norcalli
Nov 13, 2019
Author
Contributor
Nope. Any delivery order, and I did consider the same thing. I'll slap a [TODO] here so we can Ctrl-F.
-- See https://github.com/palantir/python-language-server/commit/cfd6675bc10d5e8dbc50fc50f90e4a37b7178821#diff-f68667852a14e9f761f6ebf07ba02fc8 for an example of pyls handling both. | ||
--]=] | ||
elseif true or text_document_did_change == protocol.TextDocumentSyncKind.Full then | ||
changes = full_changes(client) |
This comment has been minimized.
This comment has been minimized.
bfredl
Nov 13, 2019
Member
TODO for later: we should throttle full buffer updates in some situation like global change.
end | ||
end | ||
|
||
local function update_tagstack() |
This comment has been minimized.
This comment has been minimized.
bfredl
Nov 13, 2019
Member
TODO: this doesn't seem specific. Perhaps there should be a single-call API function to emulate tagstack?
This comment has been minimized.
This comment has been minimized.
norcalli
Nov 13, 2019
Author
Contributor
That was a leftover from the last PR, so tbh I'm not exactly sure what it does at all.
This comment has been minimized.
This comment has been minimized.
return | ||
end | ||
for client_id in pairs(client_ids) do | ||
-- This is unlikely to happen. Could only potentially happen in a race |
This comment has been minimized.
This comment has been minimized.
bfredl
Nov 13, 2019
Member
TODO: reconsider this. I think it can happen if callback()
invokes event processing which closes the client.
end | ||
local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, callback) | ||
-- TODO keep these checks or just let it go anyway? | ||
if (not client.resolved_capabilities.hover and method == 'textDocument/hover') |
This comment has been minimized.
This comment has been minimized.
bfredl
Nov 13, 2019
Member
TODO: we should make this more systematic, like a map from capability names to method names or something.
@@ -0,0 +1,45 @@ | |||
function! lsp#add_filetype_config(config) abort |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
For future travelers here, I'm trying to build an interface for common configurations so that we can have something similar to coc's servers except all in one place here https://github.com/norcalli/nvim-common-lsp. Help me get your favorite server to have an easy to use interface. Also thanks to @h-michael for keeping the old PR alive, updating it, and answering my questions, and @tjdevries for the initial PR :) Without them, this wouldn't have been possible. |
This comment has been minimized.
This comment has been minimized.
@norcalli When I got up in the morning, there was a present! Thank you for the great achievement. |
This comment has been minimized.
This comment has been minimized.
tbodt
commented
Nov 14, 2019
•
I have an alternate idea for configuration: lsp#add_config('clangd', {'cmd': 'clangd'})
autocmd FileType c,cpp lsp#set_server('clangd') This has the huge (to me) advantage of allowing you to define project-specific language server configurations, such as this in a .lvimrc: lsp#add_config('special clangd', {'cmd': ['~/project/prebuilt/bin/clangd', '-log=verbose']})
autocmd FileType c,cpp lsp#set_server('special clangd') Does this sound like a good idea? I'd be happy to write a PR for it. |
This comment has been minimized.
This comment has been minimized.
jrop
commented
Nov 14, 2019
This would be pretty sweet, actually |
This comment has been minimized.
This comment has been minimized.
@tbodt I'm guessing your comment is in response to the So, for instance, your suggestion, while better than the clangd_base_config = {
cmd = 'clangd';
}
clangd_clients = {}
vim.api.nvim_command [[autocmd FileType c,cpp lua clangd_clients[vim.lsp.start_client(vim.tbl_extend("error", clangd_base_config, { root_dir = vim.fn.expand("%:h") }))] = true]] Or something literally anything. The point is that the amount of code required is very minimal if you use Lua, whereas I found all the vimL interfaces difficult to design for because they are limited. However, as to your point of per-project configuration, if you look at the docs at https://github.com/norcalli/nvim-common-lsp#gopls, you'll see how you can do that without needing something like .lvimrc. You use the So I think I would remove all the "utility" interfaces I've added and defer to the Lua interface |
This comment has been minimized.
This comment has been minimized.
tbodt
commented
Nov 14, 2019
Agreed that |
This comment has been minimized.
This comment has been minimized.
jonhoo
commented
Nov 14, 2019
It would be really handy to have a "quick-start" guide for this feature. Just how to get set up with the basics working! |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
andymass
commented
Nov 14, 2019
Does this handle utf-16 properly? |
This comment has been minimized.
This comment has been minimized.
@andymass not yet; there are still some issues with missing byte--char conversions, but it's on top of the list mentioned in the issue mcepl mentioned. |
This comment has been minimized.
This comment has been minimized.
@andymass yeah, that's first on my agenda for today. It should be a transparent fix which makes any existing callbacks just work. |
neovim/neovim#11336 is merged.
norcalli commentedNov 5, 2019
•
edited
There are a few outstanding questions left, like:
For example, clangd supports passing
offsetEncoding
in capabilities, but this is a protocol extension, so the code must be done in lua if someone wants to pass it (this is optional, however. utf-16 works just fine).Current viml example interface:
Each server must have a unique name to identify them. There's a way to define configs from
viml
, butlua
may be necessary for advanced configuations.If one didn't want to use
lsp.add_config
and wanted more granular control thanfiletype
, they could uselsp.start_client
and thenlsp.attach_to_buffer
.I ended up rewriting about 90% of the existing PR. I tried to reduce the modules further, but I think this is as good as it gets. It could still be done, however, but putting
protocol
intoutil
orlsp
.