Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed not being able to start multiple containers for client #81

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions lsp-docker.el
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,17 @@
"Return non-nil if should log docker invocation commands"
lsp-docker-log-docker-supplemental-calls)

(defun lsp-docker--uri->path (path-mappings docker-container-name uri)
(defvar root-name-map (make-hash-table :test 'equal))

(defun lsp-docker--get-container-name-from-path (path)
(let ((key (-some (lambda (s) (if (string-prefix-p s path) s nil))
(hash-table-keys root-name-map))))
(if key
(gethash key root-name-map)
(user-error "The path %s is not prefixed by a workspace root" path)
)))

(defun lsp-docker--uri->path (path-mappings uri)
"Turn docker URI into host path.
Argument PATH-MAPPINGS dotted pair of (host-path . container-path).
Argument DOCKER-CONTAINER-NAME name to use when running container.
Expand All @@ -63,7 +73,7 @@ Argument URI the uri to translate."
(s-contains? docker-path path))
path-mappings))
(replace-regexp-in-string (format "\\(%s\\).*" remote) local path nil nil 1)
(format "/docker:%s:%s" docker-container-name path))))
(format "/docker:%s:%s" (lsp-docker--get-container-name-from-path path) path))))

(defun lsp-docker--path->uri (path-mappings path)
"Turn host PATH into docker uri.
Expand All @@ -87,6 +97,7 @@ Argument PATH the path to translate."
"Return the docker command to be executed on host.
Argument DOCKER-CONTAINER-NAME name to use for container.
Argument PATH-MAPPINGS dotted pair of (host-path . container-path).

Argument DOCKER-IMAGE-ID the docker container to run language servers with.
Argument SERVER-COMMAND the language server command to run inside the container."
(split-string
Expand All @@ -108,6 +119,7 @@ Argument SERVER-COMMAND the command to execute inside the running container."
(split-string
(format "%s exec -i %s %s" lsp-docker-command docker-container-name server-command)))


(defun lsp-docker--attach-container-name-global-suffix (container-name)
"Attach a user-specified or a default suffix (properly changing it) to the container name"
(if lsp-docker-container-name-suffix
Expand All @@ -118,6 +130,10 @@ Argument SERVER-COMMAND the command to execute inside the running container."
lsp-docker-container-name-suffix))
container-name))


(defun plist-mod (fun property list)
(plist-put list property (funcall fun (plist-get list property))))

(cl-defun lsp-docker-register-client (&key server-id
docker-server-id
path-mappings
Expand All @@ -129,26 +145,34 @@ Argument SERVER-COMMAND the command to execute inside the running container."
"Registers docker clients with lsp"
(if-let ((client (copy-lsp--client (gethash server-id lsp-clients))))
(progn
(let ((docker-container-name-full (lsp-docker--attach-container-name-global-suffix docker-container-name)))
(setf (lsp--client-server-id client) docker-server-id
(lsp--client-uri->path-fn client) (-partial #'lsp-docker--uri->path
(lsp--client-uri->path-fn client) (lambda (uri) (funcall #'lsp-docker--uri->path
path-mappings
docker-container-name-full)
uri))
(lsp--client-path->uri-fn client) (-partial #'lsp-docker--path->uri path-mappings)
(lsp--client-new-connection client) (plist-put
(lsp-stdio-connection
(lambda ()
(funcall (or launch-server-cmd-fn #'lsp-docker-launch-new-container)
docker-container-name-full
path-mappings
docker-image-id
server-command)))
:test? (lambda (&rest _)
(lsp--client-new-connection client) (list
:connect (lambda (filter sentinel name environment-fn workspace)
(let* ((docker-container-name-full
(lsp-docker--attach-container-name-global-suffix docker-container-name))
(connect-fun (plist-get
(lsp-stdio-connection
(funcall
(or launch-server-cmd-fn #'lsp-docker-launch-new-container)
docker-container-name-full
path-mappings
docker-image-id
server-command))
:connect )))
(puthash (lsp--workspace-root workspace)
docker-container-name-full
root-name-map)
1 (funcall connect-fun filter sentinel name environment-fn workspace)))
:test? (lambda (&rest _)
(-any?
(-lambda ((dir))
(f-ancestor-of? dir (buffer-file-name)))
path-mappings)))
(lsp--client-priority client) (or priority (lsp--client-priority client))))
(lsp--client-priority client) (or priority (lsp--client-priority client)))
(lsp-register-client client))
(user-error "No such client %s" server-id)))

Expand Down