emacs-lsp / lsp-python-ms

lsp-mode :heart: Microsoft's python language server
https://emacs-lsp.github.io/lsp-python-ms
BSD 3-Clause "New" or "Revised" License
190 stars 41 forks source link

Remote server solution #18

Open hek14 opened 5 years ago

hek14 commented 5 years ago

Thank you for your great job to get lsp work well with Microsoft-python-language-server. I have an issue with the lsp-python-ms: It works well on my local machine. Is there a method for starting a language server on a remote machine? When I open python files on a remote server with TRAMP, I get the error"LSP :: No LSP server for python-mode.".

yyoncho commented 5 years ago

lsp-mode supports running servers over tramp(note that the server should be installed on the remote machine). If you want to have the server on the local machine and open file on the remote then use something like sshfs.

Here it is a guide how to configure tramp with lsp-mode - https://github.com/emacs-lsp/lsp-mode#tramp-experimental

andrew-christianson commented 5 years ago

@hek14 I'd love to make this client work over the network as well - I can experiment when I have some time, but the required changes may be as small as adding the :remote? t to the client definition an insuring the search path discovery mechanisms filter out any tramp-style paths before passing them to the language server.

@yyoncho marking a client as remote shouldn't affect it's behavior for local files, right?

yyoncho commented 5 years ago

Yes. Generally registering a remote client with the proper path should be sufficient.

hek14 commented 5 years ago

Sorry for the late response. @andrew-christianson. I add the :remote? t to lsp-register-client function in ls-python-ms.el. But when I connect my remote server using tramp, I still get this error "LSP :: No LSP server for python-mode.". I have install Microsoft.Python.LanguageServer and ensure that it's in my PATH. What should I do further to make it work? I follow @yyoncho advice to use sshfs recently. But I still look forward to getting the lsp-mode work well with tramp.

yyoncho commented 5 years ago

@hek14 you should make sure that executable-find when you are in the remote file is able to find the remote python server.

alienzj commented 4 years ago

@hek14 Hi, did you solve this problem?

mjlbach commented 4 years ago

I was debugging this a bit (albeit in a separate issue) with @yyoncho. Right now, you need to manually specify the options for your remote connection it seems. For example, the following works:

(defun lsp-python-ms-dummy-params-remote (&optional workspace)
  "Return form describing parameters for language server.

Old lsp will pass in a WORKSPACE, new lsp has a global
lsp-workspace-root function that finds the current buffer's
workspace root.  If nothing works, default to the current file's
directory"
      `(:interpreter
        (:properties (
                  :InterpreterPath "/home/mjlbach/.virtualenvs/physics3.7/bin/python3"
                  :UseDefaultDatabase t
                  :Version "3.7"))
        ;; preferredFormat "markdown" or "plaintext"
        ;; experiment to find what works best -- over here mostly plaintext
        :displayOptions (:preferredFormat "markdown"
                         :trimDocumentationLines :json-false
                         :maxDocumentationLineLength 0
                         :trimDocumentationText :json-false
                         :maxDocumentationTextLength 0)
        :searchPaths ,(vconcat '(
                        "/home/mjlbach/Repositories/lab/box-physics"
                        "/home/mjlbach/.virtualenvs/physics3.7/lib64/python3.7/site-packages/_pdbpp_path_hack"
                        "/usr/lib64/python37.zip"
                        "/usr/lib64/python3.7"
                        "/usr/lib64/python3.7/lib-dynload"
                        "/home/mjlbach/.virtualenvs/physics3.7/lib64/python3.7/site-packages"
                        "/home/mjlbach/Repositories/lab/physics"
                        "/home/mjlbach/Repositories/lab/tdw-agents"
                        "/home/mjlbach/Repositories/lab/TDWBase/Python"
                        "/home/mjlbach/.virtualenvs/physics3.7/lib/python3.7/site-packages"
                        "/home/mjlbach/.virtualenvs/physics3.7/lib/python3.7/site-packages/_pdbpp_path_hack"
                   ))
        :analysisUpdates t
        :asyncStartup t
        :logLevel "Debug"
        :typeStubSearchPaths ,(vconcat '("/home/michael/.emacs.d/.local/etc/lsp/mspyls/Typeshed"))))

(after! lsp-mode
  (lsp-register-client
    (make-lsp-client :new-connection (lsp-tramp-connection "python-language-server")
                      :major-modes '(python-mode)
                      :remote? t
                      :notification-handlers (lsp-ht ("python/languageServerStarted" 'lsp-python-ms--language-server-started-callback)
                                                    ("telemetry/event" 'ignore)
                                                    ("python/reportProgress" 'lsp-python-ms--report-progress-callback)
                                                    ("python/beginProgress" 'lsp-python-ms--begin-progress-callback)
                                                    ("python/endProgress" 'lsp-python-ms--end-progress-callback))
                      :initialization-options 'lsp-python-ms--extra-init-params
                      :initialized-fn (lambda (workspace)
                                        (with-lsp-workspace workspace
                                          (lsp--set-configuration (lsp-configuration-section "python"))))
                      :server-id 'pyls-remote)))

I think the primary issue is that when setting lsp-python-ms--extra-init-params, the value for the interpreter and version is bound by calling lsp-python-ms--get-python-ver-and-syspath which ultimately calls lsp-python-ms-locate-python here: https://github.com/emacs-lsp/lsp-python-ms/blob/master/lsp-python-ms.el#L262-L269. This just uses executable-find. I'm having trouble even after setting executable-find's remote arg to true, and ensuring my virtualenv is on the exec-path (and for that matter, I tried tramp-remote-path) getting it to find the virtualenv interpreter.

Edit: Ah, apparently the function (exec-path) refers to the remote path whereas the variable exec-path refers to the local-path... confusing naming. This would explain why even with remote argument true, the function still isn't finding the virtualenv.