GitHub - emacs-lsp/lsp-docker: Scripts and configurations to leverage lsp-mode in docker environment (original) (raw)
lsp-mode
uses lsp-docker
to run language servers using in containers
Table of Contents
- Preconfigured language servers
- Usage
- emacslsp/lsp-docker-langservers
- emacslsp/lsp-docker-full
- Custom language server containers
- Docker over TRAMP (TBD)
- See also
- Maintainers
Preconfigured language servers
emacslsp/lsp-docker-langservers
has the following content:
- Language servers:
Language Language Server Bash bash-language-server C++ ccls CSS/LessCSS/SASS/SCSS css Dockerfile dockerfile-language-server-nodejs Go gopls HTML html JavaScript/TypeScript typescript-language-server Python pylsp
Usage
There are two ways of working with containerized language servers:
- 2 containers provided by
lsp-docker
: - Custom language server containers
emacslsp/lsp-docker-langservers
This container is used by lsp-docker
to run Language Servers
for lsp-mode
over local sources.You must pull the container before lsp-docker can use it
Configuration
- Clone the repo
git clone https://github.com/emacs-lsp/lsp-docker - Pull the container
docker pull emacslsp/lsp-docker-langservers - Add repo to load path and register the docker clients in your
~/.emacs
file
;; Uncomment the next line if you are using this from source
;; (add-to-list 'load-path "")
(require 'lsp-docker)
(defvar lsp-docker-client-packages
'(lsp-css lsp-clients lsp-bash lsp-go lsp-pylsp lsp-html lsp-typescript
lsp-terraform lsp-clangd))
(setq lsp-docker-client-configs
'((:server-id bash-ls :docker-server-id bashls-docker :server-command "bash-language-server start")
(:server-id clangd :docker-server-id clangd-docker :server-command "clangd")
(:server-id css-ls :docker-server-id cssls-docker :server-command "css-languageserver --stdio")
(:server-id dockerfile-ls :docker-server-id dockerfilels-docker :server-command "docker-langserver --stdio")
(:server-id gopls :docker-server-id gopls-docker :server-command "gopls")
(:server-id html-ls :docker-server-id htmls-docker :server-command "html-languageserver --stdio")
(:server-id pylsp :docker-server-id pyls-docker :server-command "pylsp")
(:server-id ts-ls :docker-server-id tsls-docker :server-command "typescript-language-server --stdio")))
(require 'lsp-docker)
(lsp-docker-init-clients
:path-mappings '(("path-to-projects-you-want-to-use" . "/projects"))
:client-packages lsp-docker-client-packages
:client-configs lsp-docker-client-configs)
How it works
lsp-mode
starts the image passed as :docker-image-id
and mounts :path-mappings
in the container. Then when the process is started lsp-mode
translates the local paths to docker
path and vice versa using the :path-mappings
specified when calling lsp-docker-init-default-clients
. You may use lsp-enabled-clients
and lsp-disabled-clients
to control what language server will be used to run for a particular project(refer to lsp-mode
FAQ on how to configure .dir-locals).
emacslsp/lsp-docker-full
The container emacslsp/lsp-docker-full
contains:
- The above language servers
Emacs28
compiled with native JSON support for better performance.
Flags
Flag | Purpose | Default |
---|---|---|
EMACS_D_VOLUME | Emacs folder to use for /root/.emacs | Emacs: (pwd)/emacs.dSpacemacs:(pwd)/emacs.d Spacemacs: (pwd)/emacs.dSpacemacs:(pwd)/spacemacs |
PROJECTS_VOLUME | Directory to mount at /Projects | $(pwd)/demo-projects/ |
TZ | Timezone to user in container | Europe/Minsk |
DOCKER_FLAGS | Any additional docker flags | N/A |
Emacs
- Clone
lsp-docker
.
git clone https://github.com/emacs-lsp/lsp-docker
cd lsp-docker - Run
Spacemacs
- Clone
lsp-docker
.
git clone https://github.com/emacs-lsp/lsp-docker
cd lsp-docker - Clone spacemacs repo
Clone spacemacs develop
git clone -b develop https://github.com/syl20bnr/spacemacs spacemacs
- Run
EMACS_D_VOLUME=/path/to/spacemacs bash start-spacemacs.sh
Custom language server containers
You can use manually built language containers or images hosting language server(s), just follow a few simple rules (shown below). The docker images may feature an optional tag, if omitted latest will be assumed.
Building a container (or an image) manually:
You have 2 constraints:
- A language server must be launched in
stdio
mode (other types of communication are yet to be supported) - A docker container (only
container
subtype, see the configuration below) must have your language server as an entrypoint (basically you have to be able to launch it withdocker start -i <container_name>
as it is launched this way withlsp-docker
)
When you have sucessfully built a language server, you have to register it with either a configuration file or a .dir-locals
file.
Registering a language server using a persistent configuration file:
A configuration file is a yaml file that can be located at:
/.lsp-docker.yml /.lsp-docker.yaml /.lsp-docker/.lsp-docker.yml /.lsp-docker/.lsp-docker.yaml /.lsp-docker/lsp-docker.yml /.lsp-docker/lsp-docker.yaml /.lsp-docker/config.yml /.lsp-docker/config.yaml
It is structured in the following way:
single server configuration
lsp:
server:
type: docker
# subtype:
# - "container": attach to an already running container
# - "image": when image does not exist, try to build it based on the dockerfile found in the project-scope
# (see Automatic image building). An image might feature an optional tag, i.e. ':'. If a
# tagless image is indicated 'latest' will be assumed.
subtype: container
# Image/container name to use for this language server.
name: image-container-name
# server id of a registered LSP server. You can find the list of registered servers evaluating:
#
# (ht-keys lsp-clients)
#
# source:
# https://stackoverflow.com/questions/17066169/retrieve-keys-from-hash-table-sorted-by-the-values-efficiently
server: server-id-of-the-base-server
# an (optional) array of parameters (docker or podman) to launch the image with
# initially intended to host the '--userns' parameter
# NOTE: 'launch_parameters' are not used with 'container' subtype servers
# in this case embed all required parameters when creating the server instead
launch_parameters:
- "--userns=nomap"
# command to launch the language server in stdio mode
# NOTE: 'launch_command' is not used with 'container' subtype servers as a command is embedded in a
# container itself and serves as entrypoint
launch_command: "launch command with arguments"
mappings:
# NOTE: the paths must be within the project this server is being build for
- source: "/your/host/source/path"
destination: "/your/path/inside/the/container"
multiple server configuration
lsp: server: - type: ... subtype: ... ... # keys as in the classic single server case, e.g. type, subtype, etc... - ... # other single server configuration(s) mappings: # shared among all servers - source: destination: ... # other mappings
Registering a language server using a .dir-locals
file:
Just refer to the source code and general conventions of using .dir-locals
. The variable you need is lsp-docker-persistent-default-config
, its content is merged with the lsp
section from a configuration file (if present).
Automatic image building:
You can also build an image automatically (currently supported only for image
subtype): just drop the corresponding Dockerfile
into the .lsp-docker
folder in the project root (Dockerfile
may be named as Dockerfile
or Dockerfile.lsp
). Building process is triggered by the lsp-docker-register
call (you will be prompted whether you want to build the image). Image building takes place in the project root (not in the .lsp-docker
subfolder)! In case of an automatic build the image will be registered automatically (based on the values from the config or .dir-locals
file).
You can also troubleshoot any issues with supplemental docker calls (checking whether the required image already exists, building a new image) using the supplemental logging functionality: there are 2 variables: first you have to set lsp-docker-log-docker-supplemental-calls
to true-like value (by default it is nil
) and then specify the log buffer in the lsp-docker-log-docker-supplemental-calls-buffer-name
variable (by default it is set to *lsp-docker-supplemental-calls*
)
Docker over TRAMP (TBD)
Docker running the language servers and hosting the sources, Emacs running on the desktop machine and connecting to docker instance over TRAMP.
See also
- docker - package for managing
docker
images/containers.