lsp-docker
lsp-docker copied to clipboard
Scripts and configurations to leverage lsp-mode in docker environment
#+ATTR_HTML: align="center"; margin-right="auto"; margin-left="auto" =lsp-mode= uses =lsp-docker= to run language servers using in containers
[[./images/logo.png]]
- Table of Contents :TOC_4_gh:noexport:
- [[#preconfigured-language-servers][Preconfigured language servers]]
- [[#usage][Usage]]
- [[#emacslsplsp-docker-langservers][emacslsp/lsp-docker-langservers]]
- [[#configuration][Configuration]]
- [[#how-it-works][How it works]]
- [[#emacslsplsp-docker-full][emacslsp/lsp-docker-full]]
- [[#flags][Flags]]
- [[#emacs][Emacs]]
- [[#spacemacs][Spacemacs]]
- [[#flags][Flags]]
- [[#custom-language-server-containers][Custom language server containers]]
- [[#docker-over-tramp-tbd][Docker over TRAMP (TBD)]]
- [[#see-also][See also]]
- [[#maintainers][Maintainers]]
** Preconfigured language servers =emacslsp/lsp-docker-langservers= has the following content:
- Language servers: | Language | Language Server | |-----------------------+-----------------------------------| | Bash | [[https://github.com/mads-hartmann/bash-language-server][bash-language-server]] | | C++ | [[https://github.com/MaskRay/ccls][ccls]] | | CSS/LessCSS/SASS/SCSS | [[https://github.com/vscode-langservers/vscode-css-languageserver-bin][css]] | | Dockerfile | [[https://github.com/rcjsuen/dockerfile-language-server-nodejs][dockerfile-language-server-nodejs]] | | Go | [[https://golang.org/x/tools/cmd/gopls][gopls]] | | HTML | [[https://github.com/vscode-langservers/vscode-html-languageserver][html]] | | JavaScript/TypeScript | [[https://github.com/theia-ide/typescript-language-server][typescript-language-server]] | | Python | [[https://github.com/palantir/python-language-server][pyls]] | ** Usage There are two ways of working with containerized language servers:
- 2 containers provided by =lsp-docker=:
- [[#emacslsplsp-docker-langservers][emacslsp/lsp-docker-langservers]]
- [[#emacslsplsp-docker-full][emacslsp/lsp-docker-full]]
- [[#custom-language-server-containers][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
#+begin_src bash
git clone https://github.com/emacs-lsp/lsp-docker
#+end_src
- Pull the container
#+begin_src bash
docker pull emacslsp/lsp-docker-langservers
#+end_src
- Add repo to load path and register the docker clients in your =~/.emacs= file
#+begin_src elisp
;; Uncomment the next line if you are using this from source
;; (add-to-list 'load-path "
(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)
#+end_src
*** 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=. #+begin_src bash git clone https://github.com/emacs-lsp/lsp-docker cd lsp-docker #+end_src - Run #+begin_src bash bash start-emacs.sh #+end_src **** Spacemacs - Clone =lsp-docker=. #+begin_src bash git clone https://github.com/emacs-lsp/lsp-docker cd lsp-docker #+end_src - Clone spacemacs repo #+begin_src bash # Clone spacemacs develop git clone -b develop https://github.com/syl20bnr/spacemacs spacemacs #+end_src - Run #+begin_src bash EMACS_D_VOLUME=/path/to/spacemacs bash start-spacemacs.sh #+end_src
** 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 with =docker start -i <container_name>= as it is launched this way with =lsp-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: #+begin_src yaml 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" #+end_src
*** 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).
** 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
- [[https://github.com/Silex/docker.el][docker]] - package for managing =docker= images/containers. ** Maintainers
- [[https://github.com/yyoncho][yyoncho]]
- [[https://github.com/rnikoopour][rnikoopour]]