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 pyls
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 "<path-to-lsp-docker-dir>") (require 'lsp-docker) (defvar lsp-docker-client-packages '(lsp-css lsp-clients lsp-bash lsp-go lsp-pyls 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 pyls :docker-server-id pyls-docker :server-command "pyls") (: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.d Spacemacs: $(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
bash start-emacs.sh
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).
Building a container (or an image):
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 is named .lsp-docker.yml
or .lsp-docker.yaml
and looks generally like this:
lsp:
server:
type: docker
subtype: container # Or image. container subtype means launching an existing container
# image subtype means creating a new container each time from a specified image
name: not-significant-but-unique-name # Must be unique across all language servers
server: server-id-of-the-base-server # Server id of a registered server (by lsp-mode)
launch_command: "launch command with arguments" # Launch command of the language server
# (selected by a server id specified above) 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 an entrypoint
mappings:
- source: "/your/host/source/path"
destination: "/your/local/path/inside/a/container"
.dir-locals
file:
Registering a language server using a 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).
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.