# lsp-adapter **Repository Path**: mirrors_sourcegraph/lsp-adapter ## Basic Information - **Project Name**: lsp-adapter - **Description**: lsp-adapter provides a proxy which adapts Sourcegraph LSP requests to vanilla LSP requests - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-23 - **Last Updated**: 2026-05-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # lsp-adapter [![Travis-CI](https://travis-ci.org/sourcegraph/lsp-adapter.svg)](https://travis-ci.org/sourcegraph/lsp-adapter) [![AppVeyor](https://ci.appveyor.com/api/projects/status/vfdftcqh0ekb881u/branch/master?svg=true)](https://ci.appveyor.com/project/sourcegraph/lsp-adapter/branch/master) [![GoDoc](https://godoc.org/github.com/sourcegraph/lsp-adapter?status.svg)](http://godoc.org/github.com/sourcegraph/lsp-adapter) [![Go Report Card](https://goreportcard.com/badge/github.com/sourcegraph/lsp-adapter)](https://goreportcard.com/report/github.com/sourcegraph/lsp-adapter) Command `lsp-adapter` provides a proxy which adapts Sourcegraph LSP requests to vanilla LSP requests. ## Background [Code Intelligence on Sourcegraph](https://about.sourcegraph.com/docs/code-intelligence/) is powered by the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). Previously, language servers that were used on sourcegraph.com were additionally required to support our custom LSP [files extensions](https://github.com/sourcegraph/language-server-protocol/blob/master/extension-files.md). These extensions allowed language servers to operate without sharing a physical file system with the client. While it's preferable for language servers to implement these extensions for performance reasons, implementing this functionality is a large undertaking. `lsp-adapter` eliminates the need for this requirement, which allows off-the-shelf language servers to be able to provide basic functionality (hovers, local definitions) to Sourcegraph. ## How to Install You can download the latest binary on the [releases page](https://github.com/sourcegraph/lsp-adapter/releases). Alternatively, install it with `go get`: ```shell go get -u -v github.com/sourcegraph/lsp-adapter ``` Running `lsp-adapter --help` shows you some of its options: ```shell > lsp-adapter --help Usage: lsp-adapter [OPTIONS] LSP_COMMAND_ARGS... Options: -beforeInitializeHook string A program to run after cloning the repository, but before the 'initialize' call is forwarded to the language server. (For example, you can use this to run a script to install dependencies for the project). The program's cwd will be the workspace's cache directory, and it will also be passed the cache directory as an argument. -cacheDirectory string cache directory location (default "/var/folders/qq/1q_cmsmx6qv7bs_m6g_2pt1r0000gn/T/proxy-cache") -didOpenLanguage string (HACK) If non-empty, send 'textDocument/didOpen' notifications with the specified language field (e.x. 'python') to the language server for every file. -glob string A colon (:) separated list of file globs to sync locally. By default we place all files into the workspace, but some language servers may only look at a subset of files. Specifying this allows us to avoid syncing all files. Note: This is done by basename only. -jsonrpc2IDRewrite string (HACK) Rewrite jsonrpc2 ID. none (default) is no rewriting. string will use a string ID. number will use number ID. Useful for language servers with non-spec complaint JSONRPC2 implementations. (default "none") -pprofAddr string server listen address for pprof -proxyAddress string proxy server listen address (tcp) (default "127.0.0.1:8080") -trace trace logs to stderr (default true) ``` ## How to Use `lsp-adapter` `lsp-adapter` proxies requests between your Sourcegraph instance and the language server, and modifies them in such a way that allows for the two to communicate correctly. In order to do this, we need to know - How to connect `lsp-adapter` to the language server - How to connect to your Sourcegraph instance to `lsp-adapter` ### Connect `lsp-adapter` to the Language Server `lsp-adapter` can talk to language servers over standard I/O. `lsp-adapter` interprets any positional arguments after the flags as the necessary command (+ arguments) to start the language server binary. It uses this command to communicate to the language server inside of a subprocess. For example, if I am trying to use Rust’s language server, the command to start it up is just `rls`. `lsp-adapter` can be told to start the start the same server via: ```shell lsp-adapter rls ``` Any stderr output from the binary will also appear in `lsp-adapter`'s logs. ### Connect Sourcegraph to `lsp-adapter` 1. Use the `-proxyAddress` flag to tell `lsp-adapter` what address to listen for connections from Sourcegraph on. For example, I can tell `lsp-adapter` to listen on my local `8080` port with `-proxyAddress=127.0.0.1:8080`. 2. We then need to add a new entry to the `"langservers"` field in the site configuration in order to point Sourcegraph at `lsp-adapter` (similar to the steps in [this document](https://about.sourcegraph.com/docs/code-intelligence/install-manual)). For example, if `lsp-adapter` is connected to the Rust language server, and the `lsp-adapter` itself is listening on `127.0.0.1:8080`: ```json { "language": "rust", "address": "tcp://127.0.0.1:8080" } ``` would be the new entry that needs to be added to the `"langservers"` field. ## Example Commands Connect via standard I/O to a language server whose command can be run with `rls`, and listen for connections from Sourcegraph from any address on port `1234`. ```shell > lsp-adapter -proxyAddresss=0.0.0.0:1234 rls 2018/04/04 15:27:04 proxy.go:71: CloneProxy: accepting connections at [::]:8080 ``` Connect via standard I/O to a language server whose command can be run with `rls`, change the location of the cache directory (used for cloning the repo locally) to `/tmpDir`, and enable tracing for every request to/from the language server. ```shell > lsp-adapter -cacheDir='/tmpDir' -trace rls ``` ## Docker There is a [skeleton Dockerfile](./Dockerfile) that shows how to package `lsp-adapter` along with your desired language server inside of a docker container. There are fully working examples in [dockerfiles](./dockerfiles). For example [dockerfiles/rust/Dockerfile](./dockerfiles/rust/Dockerfile), which can be built with: ```shell > docker build -f dockerfiles/rust/Dockerfile . ``` ## Glob Most language servers will only ever look at files that match a set of known patterns. On initialize lsp-adapter copies a full work-tree to disk for a repository, but by specifying `-glob` we can avoid copying over files that will not be looked at. For example, if a python language server only looks at `py` and `pyc` files you can specify `-glob=*.py:*.pyc`. The matching is done on the basename of the path using [path.Match](https://godoc.org/path#Match). ## Did Open Hack Some language servers do not follow the LSP spec correctly and refuse to work unless the `textDocument/didOpen` notification has been sent. See [this commit](https://github.com/sourcegraph/lsp-adapter/commit/1228a1fbaf102aa44575cec6802a5a211d117ee1) for more context. If the language server that you’re trying to use has this issue, try setting the `didOpenLanguage` flag (example: if a python language server had this issue - use `./lsp-adapter -didOpenLanguage=python ...`) to work around it. ## JSONRPC2 ID Rewrite Hack Some language servers do not follow the JSONRPC2 spec correctly and fail if the Request ID is not a number of string. If the language server that you’re trying to use has this issue, try setting the `jsonrpc2IDRewrite` flag (example: if a rust language server had this issue - use `./lsp-adapter -jsonrpc2IDRewrite=number ...`) to work around it. ## Before Initialization Hook Some language servers need to run setup scripts (to install dependencies, for example) in order to provide code intelligence. By using the `-beforeInitializeHook` flag, you can specify a program/script that will run after the repository is cloned to workspace's cache directory, but before the language server receives the `initalize` request. The program's `cwd` will be the cache directory (which will also be passed as an argument for convenience). For example, if you have the following script named `hook.sh`: ```shell #!/bin/sh set -x echo $(pwd) ``` After specifying the hook via `lsp-adapter -beforeInitializeHook='/test.sh'` You will see output like ```shell 2018/06/20 21:11:45 uris.go:25: Cloned workspace to /tmp/proxy-cache/3bb76102-a73b-4442-a03e-930c59e1fdcb 2018/06/20 21:11:45 hook.go:26: Running pre-init hook: '/test.sh /tmp/proxy-cache/3bb76102-a73b-4442-a03e-930c59e1fdcb' ++ pwd + echo /Users/ggilmore/dev/go/src/github.com/sourcegraph/lsp-adapter /Users/ggilmore/dev/go/src/github.com/sourcegraph/lsp-adapter ``` every time the language sever receives an `initialize` request. Obviously, you should replace this script with something meaningful.