What is the Language Server Protocol
A language server protocol is a software that analysis the current state of a project in terms of error, syntax, format, and will exchange this information to an external program through a json format.
The idea behind the Language Server Protocol (LSP) is to standardize the protocol for how tools and servers communicate, so a single Language Server can be re-used in multiple development tools, and tools can support languages with minimal effort.
A development tool will interact with the LSP by means of JSON-RPC protocl what-is-rpc, and the LSP will reply sending the relevant information like diagnostics and completion.
E.g.:
- The user opens a file (referred to as a document) in the tool: The tool notifies the language server that a document is open (
textDocument/didOpen
). From now on, the truth about the contents of the document is no longer on the file system but kept by the tool in memory. The contents now has to be synchronized between the tool and the language server. - The user makes edits: The tool notifies the server about the document change (
textDocument/didChange
) and the language representation of the document is updated by the language server. As this happens, the language server analyses this information and notifies the tool with the detected errors and warnings (textDocument/publishDiagnostics
). - The user executes “Go to Definition” on a symbol of an open document: The tool sends a
textDocument/definition
request with two parameters: (1) the document URI and (2) the text position from where the “Go to Definition” request was initiated to the server. The server responds with the document URI and the position of the symbol’s definition inside the document. - The user closes the document (file): A
textDocument/didClose
notification is sent from the tool informing the language server that the document is now no longer in memory. The current contents are now up to date on the file system.
The data types exchanged between the development tool and the LSP are language agnostic. This means that a single tool can implement the middleware to communicate with all the LSP, therefore adding support for every language that has an LSP.
When a user is working with different languages, a development tool usually starts a language server for each programming language.
Not every language server can support all features defined by the protocol. LSP therefore provides ‘capabilities’. A capability groups a set of language features. A development tool and the language server announce their supported features using capabilities.
Example of payload:
textDocument/definition
request:
1{
2 "jsonrpc": "2.0",
3 "id" : 1,
4 "method": "textDocument/definition",
5 "params": {
6 "textDocument": {
7 "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/use.cpp"
8 },
9 "position": {
10 "line": 3,
11 "character": 12
12 }
13 }
14}
textDocument/definition
response:
1{
2 "jsonrpc": "2.0",
3 "id": 1,
4 "result": {
5 "uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/provide.cpp",
6 "range": {
7 "start": {
8 "line": 0,
9 "character": 4
10 },
11 "end": {
12 "line": 0,
13 "character": 11
14 }
15 }
16 }
17}
References
#json #editor #data #exchange #descriptor #coding #socket #completion #lsp #programming #language_server_protocol