Languageclient-neovim: interaction with clangd running inside docker container

Created on 19 Feb 2019  路  2Comments  路  Source: autozimu/LanguageClient-neovim

Hey all,

this is not yet a bug report nor a feature request, I'm merely curious whether it's possible to run the language server in a docker container and letting LanguageClient-neovim connect to it. I tried the following, but it seems the channel gets closed before any completion request is send.

let g:LanguageClient_serverCommands = {
    \ 'cpp': ['docker', 'attach', '$(docker container exec -d <container-name> clangd-7)']
    \ } 
let g:LanguageClient_serverCommands = {
    \ 'cpp': ['docker', 'container', 'exec', '-d', '<container-name>', 'clangd-7']
    \ } 

Using the flags -i -t or -i ended up in the following error message, too.

[LC] sending on a disconnected channel

Am I doing something completely wrong here? Is it even possible to let the server run inside a container?
If you think this is could be a bug/feature request, I'll assemble a MWE and elaborate on the problem.

Thanks!

Most helpful comment

Hi @autozimu ,

thanks for your quick reply and sorry for my late one... I have thought on going the tcp route as well (sry for the pun), but clangd doesn't support it out-of-the-box. So I hoped for another way.

This won't work as it's not clear which process is handling the attached stdin/stdout etc inside the container.

Thanks for the clarification! I haven't thought about this.

For people with similar problems, here is my current workaround:

  1. Start a docker container from an image and publish some port. Create a volume and keep the directory structure as on your host system, since languageclient-neovim expects the correct absolute path.

    docker run --name=<container_name> -p 50505:50505 -v $(pwd):$(pwd) -w $(pwd) -it <image_name> bash -l
    
  2. Start the container.

    docker container start <container_name>
    
  3. Launch clangd inside the container and redirect IO to the some port. (I use socat to do so.)

    docker exec -it <container_name> socat tcp-listen:50505,reuseaddr exec:clangd-7
    
  4. In your vimrc, specify the server command like @autozimu already described.

    let g:LanguageClient_serverCommands = {
        \ 'cpp': ['tcp://127.0.0.1:50505'],
        \ 'c': ['tcp://127.0.0.1:50505'],
        \ } 
    
  5. Now, :LanguageClientStart will work as usual. However, :LanguageClientStop will quit clangd and 3. needs to be executed again before another call to :LanguageClientStart!

All 2 comments

It seems that you're trying to attach directly to a docker instance. This won't work as it's not clear which process is handling the attached stdin/stdout etc inside the container.

If you would like to have the language server running in a container,

  1. start the server in a container, with it listening on a tcp port
  2. for client config, use something like
let g:LanguageClient_serverCommands = {
    \ 'cpp': ['tcp://your-container-ip:your-language-server-port']
    \ }

Hi @autozimu ,

thanks for your quick reply and sorry for my late one... I have thought on going the tcp route as well (sry for the pun), but clangd doesn't support it out-of-the-box. So I hoped for another way.

This won't work as it's not clear which process is handling the attached stdin/stdout etc inside the container.

Thanks for the clarification! I haven't thought about this.

For people with similar problems, here is my current workaround:

  1. Start a docker container from an image and publish some port. Create a volume and keep the directory structure as on your host system, since languageclient-neovim expects the correct absolute path.

    docker run --name=<container_name> -p 50505:50505 -v $(pwd):$(pwd) -w $(pwd) -it <image_name> bash -l
    
  2. Start the container.

    docker container start <container_name>
    
  3. Launch clangd inside the container and redirect IO to the some port. (I use socat to do so.)

    docker exec -it <container_name> socat tcp-listen:50505,reuseaddr exec:clangd-7
    
  4. In your vimrc, specify the server command like @autozimu already described.

    let g:LanguageClient_serverCommands = {
        \ 'cpp': ['tcp://127.0.0.1:50505'],
        \ 'c': ['tcp://127.0.0.1:50505'],
        \ } 
    
  5. Now, :LanguageClientStart will work as usual. However, :LanguageClientStop will quit clangd and 3. needs to be executed again before another call to :LanguageClientStart!

Was this page helpful?
0 / 5 - 0 ratings