Closed mjlbach closed 4 years ago
I am not using the remote env to develop and test Python files. Would you please create a PR?
I can make something for the documentation, I'll work on trying to upstream something with pyenv, poetry.el, and pipenv.
@mjlbach can u try the latest version?
I don't think anything pertinent has changed? I'm on the latest version. The above snippet I provided still works given you set the appropriate remote interpreter with pyvenv. This is more a documentation issue (I have my qualifying exams this week so I haven't been able to work on this).
The bigger ecosystem issue pyvenv/poetry don't support remote virtual environments. What I did above was a hack where I just use pyvenv and filter out the tramp prepended path to pass it to the server initialization options.
@mjlbach thanks for sharing your setup, it works for me as well!
The following clients were selected based on priority: (server-id pyright-remote, priority 3)
Pyright language server 1.1.63 starting
Server root directory: /usr/local/lib/node_modules/pyright/dist/
No configuration file found.
Setting pythonPath for service "<REDACTED>": "/usr/bin/python"
stubPath <REDACTED>/typings is not a valid directory.
Python version 2.7 from interpreter is unsupported
Assuming Python platform Linux
Searching for source files
Found 22 source files
@mjlbach Thank you so much for saving my time. For those who use conda, can refer to https://github.com/emacs-lsp/lsp-pyright/issues/7 to set up python.pythonPath
and python.venvPath
in emacs or pyrightconfig.json
@seagle0128 Here's a small problem. python.pythonPath
was not set correctly when I edit tramp buffers. since lsp-pyright-locate-python cannot get remote python's path. I tried to comment on this line L197 of code, pyright works both on local or remote. Is there a point to this line of code. Is it possible to remove or make lsp-pyright-locate-python
support finding remote python by simply adding t as an argument to executable-find(e.g. (executable-find lsp-pyright-python-executable-cmd t)
)
Thanks, @tshu-w . I updated lsp-pyright-locate-python
to search remote python cmd.
Just want to mention that the reason for asking users to create their remote registration is the lack of manpower to support one more configuration mode. So, in this case, if there is interest IMO the tramp configuration might live in the repo.
@seagle0128 I think this will only work if tramp's remote path is amended to prepend the virtual environment path. It doesn't, for example, read from the virtual environment path set by pyenv like the snippet I posted does.
@seagle0128 I think this will only work if tramp's remote path is amended to prepend the virtual environment path. It doesn't, for example, read from the virtual environment path set by pyenv like the snippet I posted does.
The commit doesn't resolve the remote venv issue. As you mentioned, it needs upstreams supports. Anyway, the PRs are welcome.
Just to concretize what needs to be upstreamed (for the benefit of others):
I have a dirty hack that works with poetry.el to support this:
diff --git a/poetry.el b/poetry.el
index 275ce85..2188120 100644
--- a/poetry.el
+++ b/poetry.el
@@ -681,7 +681,7 @@ compilation buffer name."
default-directory)))
(unless (member command '(new init config))
(poetry-ensure-in-project))
- (let* ((prog (or (executable-find "poetry")
+ (let* ((prog (or (executable-find "poetry" t)
(poetry-error "Could not find 'poetry' executable")))
(args (if (or (string= command "run")
(string= command "config")
@@ -896,7 +896,9 @@ If OPT is non-nil, set an optional dep."
".venv")
;; virtualenvs elsewhere
(car (directory-files
- (poetry-get-configuration "virtualenvs.path")
+ (concat (file-remote-p default-directory)
+ (poetry-get-configuration "virtualenvs.path")
+ )
t
(format "^%s-.+-py.*$"
(downcase (replace-regexp-in-string "_" "-" (poetry-get-project-name)))))))
I've had mixed success with lsp-pyright over tramp. I sorted out some path issues (system node is ancient and was being used by pyright), but most of the time pyright starts but then does not appear to communicate:
Command "pyright-langserver --stdio" is present on the path.
Command "pyright-langserver --stdio" is present on the path.
Found the following clients for /ssh:XXX:/YYY/ZZZ.py: (server-id pyright-remote, priority 3)
The following clients were selected based on priority: (server-id pyright-remote, priority 3)
Pyright language server 1.1.111 starting
Server root directory: /usr/local/lib/node_modules/pyright/dist/
But then... nothing, and nothing on stderr
in /tmp/pyright-remote-1-stderr
, and no capabilities in lsp-describe-session
. When it has worked, it occasionally locks up hard, and a pkill -SIGUSR2 Emacs
is needed to recover control. In this case it's usually hanging with tramp waiting for process output. While pyright-langserver
is stuck doing nothing, other tramp commands still work fine.
Has anyone had this experience or have suggestions to overcome it?
@jdtsmith There are some discussions at https://github.com/emacs-lsp/lsp-mode/issues/2375 https://github.com/emacs-lsp/lsp-mode/issues/1845
Thanks. I see those are related to \n
conversion, but here I don't even see any output to stderr or otherwise, so it's hard to conclude it's the same thing. The pyright-langserver
is running but not communicating. It would be useful to have a simple "ping the server" command in emacs-lsp
to see if the connection is actually functioning and producing sensible results. What's strange is that rarely, sometimes after an lsp-workspace-restart
, sometimes on a fresh start, the server seems to function for a while, usually locking up after that in an apparent tramp-related blockage.
@jdtsmith In fact I was troubled by the same problem as you before, many times no error was reported, just stuck and a reboot might work. Since upgrading to emacs28 this phenomenon has been significantly alleviated.
Interesting. Do you believe this is due to Emacs 28 improvements with tramp? I have set tramp-verbose
to 7 or so to watch the traffic, but there's nothing obviously broken there. Either information is flowing to the server, or it is not.
I have wondered whether the watch file capability is freezing pyright. When it works it always says:
Creating watch for /ssh:XXX:/XXX/YYY/ZZZ.py
Failed to create a watch for No file notification program found on /ssh:XXX:: message
Does anyone have a suggestion to ping/probe a running server separate from Emacs/tramp, to check whether it's a LSP server issue or an Emacs/tramp issue? Equivalent to telnetting to port 80 to see if an httpd server is running & communicating...
Do you believe this is due to Emacs 28 improvements with tramp
Yes, according to here https://github.com/emacs-lsp/lsp-mode/issues/2375#issuecomment-749132863:
Michael fixed the issue in the tramp code
You can run it directly on the server, I'm not sure how to communicate with it, but I suggest discussing it directly at lsp-mode, I don't think it's a pyright issue.
I found that lsp-mode PR #2531 did the trick for me (+ upgrading Tramp to v2.5). I didn't need to update Emacs itself.
I found that lsp-mode PR #2531 did the trick for me (+ upgrading Tramp to v2.5). I didn't need to update Emacs itself.
Just want to confirm that this works to me as well.
Hello
I've followed instructions on this thread and, as @tshu-w suggested, here, to setup lsp-mode with conda and pyright on a remote server, but I am still running into problems.
LSP :: There are no language servers supporting current mode `python-mode' registered with `lsp-mode'.
This issue might be caused by:
1. The language you are trying to use does not have built-in support in `lsp-mode'. You must install the required support manually. Examples of this are `lsp-java' or `lsp-metals'.
2. The language server that you expect to run is not configured to run for major mode `python-mode'. You may check that by checking the `:major-modes' that are passed to `lsp-register-client'.
3. `lsp-mode' doesn't have any integration for the language behind `python-mode'. Refer to https://emacs-lsp.github.io/lsp-mode/page/languages and https://langserver.org/ .
4. You are over `tramp'. In this case follow https://emacs-lsp.github.io/lsp-mode/page/remote/.
5. You have disabled the `lsp-mode' clients for that file. (Check `lsp-enabled-clients' and `lsp-disabled-clients').
This is in my doom-emacs config.el
, which is basically what @mjlbach suggested.
(setq enable-remote-dir-locals t)
(setq enable-local-variables :all)
(use-package! lsp-mode
:commands lsp
:hook
(python-mode . lsp))
(after! lsp-clients
(setq lsp-log-io t)
(setq lsp-pyright-use-library-code-for-types t)
(setq lsp-pyright-diagnostic-mode "workspace")
(lsp-register-client
(make-lsp-client
:new-connection (lsp-tramp-connection (lambda ()
(cons "pyright-langserver"
lsp-pyright-langserver-command-args)))
:major-modes '(python-mode)
:remote? t
:server-id 'pyright-remote
:multi-root t
:priority 3
:initialization-options (lambda () (ht-merge (lsp-configuration-section "pyright")
(lsp-configuration-section "python")))
:initialized-fn (lambda (workspace)
(with-lsp-workspace workspace
(lsp--set-configuration
(ht-merge (lsp-configuration-section "pyright")
(lsp-configuration-section "python")))))
:download-server-fn (lambda (_client callback error-callback _update?)
(lsp-package-ensure 'pyright callback error-callback))
:notification-handlers (lsp-ht ("pyright/beginProgress" 'lsp-pyright--begin-progress-callback)
("pyright/reportProgress" 'lsp-pyright--report-progress-callback)
("pyright/endProgress" 'lsp-pyright--end-progress-callback))))
)
In my project directory, I made a new .dir-locals.el
file with the follow contents, like what @tshu-w suggested in the other thread.
((python-mode . ((eval . (lsp-register-custom-settings
'(("python.pythonPath" "~/anaconda3/envs/python37/bin/python"
"python.venvPath" "~/anaconda3/envs/python37")))))))
Anyone knows what I'm missing?
@mjlbach, I note that you have tried this with doom-emacs: https://github.com/hlissner/doom-emacs/issues/3390#issuecomment-667708051. Anything I should take note of?
@jdtsmith You should paste the content of *lsp-log*
. Does every thing work fine on local. What's the results if you run M-: (executable-find "pyright" t)
when open tramp buffers. My current guess is that you may need the following config:
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
Hi @tshu-w. Thanks for responding!
I don't have lsp setup locally as I do all my work on a remote filesystem so I don't even have my conda env etc on my local machine.
I couldn't find *lsp-log*
in my list of buffers after opening a remote .py
file.
Running M-: (executable-find "pyright" t)
returns nil
.
Interestingly, I couldn't add that line to my doom-emacs config.el
. Here's the backtrace.
(member 'tramp-own-remote-path tramp-remote-path)
(if (member 'tramp-own-remote-path tramp-remote-path) tramp-remote-path (setq tramp-remote-path (cons 'tramp-own-remote-path tramp-remote-path)))
eval-buffer(#<buffer *load*-149563> nil "/home/user/.doom.d/config.el" nil t) ; Reading at buffer position 3775
load-with-code-conversion("/home/user/.doom.d/config.el" "/home/user/.doom.d/config.el" t t)
load("/home/user/.doom.d/config" t nomessage)
(let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage))
(condition-case e (let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name "config" doom-private-dir) doom-private-dir)))
(if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name "config" doom-private-dir) doom-private-dir))) (if custom-file (progn (load custom-file 'noerror (not doom-debug-mode)))))
(progn (if doom-debug-p (progn (let ((inhibit-message (active-minibuffer-window))) (message #("DOOM Initializing user config" 0 5 (face font-lock-comment-face)))))) (maphash (doom-module-loader doom-module-init-file) doom-modules) (doom-run-hooks 'doom-before-init-modules-hook) (if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name "config" doom-private-dir) doom-private-dir))) (if custom-file (progn (load custom-file 'noerror (not doom-debug-mode))))))
(if init-p (progn (if doom-debug-p (progn (let ((inhibit-message (active-minibuffer-window))) (message #("DOOM Initializing user config" 0 5 (face font-lock-comment-face)))))) (maphash (doom-module-loader doom-module-init-file) doom-modules) (doom-run-hooks 'doom-before-init-modules-hook) (if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name "config" doom-private-dir) doom-private-dir))) (if custom-file (progn (load custom-file 'noerror (not doom-debug-mode)))))) nil)
(let* ((init-p (and t (condition-case e (let (file-name-handler-alist) (load (expand-file-name doom-module-init-file doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name doom-module-init-file doom-private-dir) doom-private-dir)))))) (if init-p (progn (if doom-debug-p (progn (let ((inhibit-message ...)) (message #("DOOM Initializing user config" 0 5 ...))))) (maphash (doom-module-loader doom-module-init-file) doom-modules) (doom-run-hooks 'doom-before-init-modules-hook) (if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let (file-name-handler-alist) (load (expand-file-name "config" doom-private-dir) t 'nomessage)) ((debug doom-error) (signal (car e) (cdr e))) ((debug error) (doom--handle-load-error e (expand-file-name "config" doom-private-dir) doom-private-dir))) (if custom-file (progn (load custom-file 'noerror (not doom-debug-mode)))))) nil))
(progn (setq doom-init-modules-p t) (if no-config-p nil (if doom-debug-p (progn (let ((inhibit-message (active-minibuffer-window))) (message #("DOOM Initializing core modules" 0 5 (face font-lock-comment-face)))))) (doom-initialize-core-modules)) (let* ((init-p (and t (condition-case e (let (file-name-handler-alist) (load ... t ...)) ((debug doom-error) (signal ... ...)) ((debug error) (doom--handle-load-error e ... doom-private-dir)))))) (if init-p (progn (if doom-debug-p (progn (let (...) (message ...)))) (maphash (doom-module-loader doom-module-init-file) doom-modules) (doom-run-hooks 'doom-before-init-modules-hook) (if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let (file-name-handler-alist) (load ... t ...)) ((debug doom-error) (signal ... ...)) ((debug error) (doom--handle-load-error e ... doom-private-dir))) (if custom-file (progn (load custom-file ... ...))))) nil)))
(if (or force-p (not doom-init-modules-p)) (progn (setq doom-init-modules-p t) (if no-config-p nil (if doom-debug-p (progn (let ((inhibit-message ...)) (message #("DOOM Initializing core modules" 0 5 ...))))) (doom-initialize-core-modules)) (let* ((init-p (and t (condition-case e (let ... ...) (... ...) (... ...))))) (if init-p (progn (if doom-debug-p (progn (let ... ...))) (maphash (doom-module-loader doom-module-init-file) doom-modules) (doom-run-hooks 'doom-before-init-modules-hook) (if no-config-p nil (maphash (doom-module-loader doom-module-config-file) doom-modules) (doom-run-hooks 'doom-init-modules-hook) (condition-case e (let ... ...) (... ...) (... ...)) (if custom-file (progn ...)))) nil))))
doom-initialize-modules()
eval-buffer(#<buffer *load*-168617> nil "/home/user/doom-emacs/init.el" nil t) ; Reading at buffer position 2804
load-with-code-conversion("/home/user/doom-emacs/init.el" "/home/user/doom-emacs/init.el" t t)
load("/home/user/doom-emacs/init.el" t t)
(let ((init-file (expand-file-name "init.el" user-emacs-directory))) (load init-file t t) (let ((chemacs-custom-file (chemacs-profile-get 'custom-file init-file))) (if (not custom-file) (progn (setq custom-file chemacs-custom-file) (if (equal custom-file init-file) nil (if (file-exists-p custom-file) nil (let (...) (save-current-buffer ... ...))) (load custom-file))))))
chemacs-load-user-init()
eval-buffer(#<buffer *load*> nil "/home/user/.emacs.d/init.el" nil t) ; Reading at buffer position 238
load-with-code-conversion("/home/user/.emacs.d/init.el" "/home/user/.emacs.d/init.el" t t)
load("/home/user/.emacs.d/init" noerror nomessage)
startup--load-user-init-file(#f(compiled-function () #<bytecode 0x156ad29bc331>) #f(compiled-function () #<bytecode 0x156ad29bc349>) t)
command-line()
normal-top-level()
Any idea what's wrong?
@tshu-w, okay I fixed it with:
(after! tramp
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
However, running M-: (executable-find "pyright" t)
still returns nil
.
The current problem is that Emacs cannot find your remote pyright. Can you run pyright on remote shell?
In my project directory, I made a new
.dir-locals.el
file with the follow contents, like what @tshu-w suggested in the other thread.
BTW, .dir-locals.el
is only needed when you need a non-base environment if you can find the python path via executable-find.
Yes, I don't use the base environment on conda, so I guess .dir-locals.el
is required.
Here I attempt to run pyright on the remote shell (but not from within a shell in emacs) after I activate the appropriate conda environment python37
. Looks like there are also problems with pyright itself? It's my first time using, so I'm not sure.
$ ssh ws1
$ conda activate python37
(python37) $ pyright
No configuration file found.
No pyproject.toml file found.
stubPath ~/typings is not a valid directory.
Assuming Python platform Linux
Searching for source files
Skipping broken link "~/.cache/edm/packages/1c/09b80682943d242f6eee3a79276a18c76d7962c7e49e329e98179f3762abce/traitsui-5.1.0-2.egg/traitsui/image/library/icons.zip"
Skipping broken link "~/.cache/edm/packages/1c/09b80682943d242f6eee3a79276a18c76d7962c7e49e329e98179f3762abce/traitsui-5.1.0-2.egg/traitsui/image/library/std.zip"
Skipping broken link "~/.cache/edm/packages/8b/8df08a725117b8d62702fa63888f9ea96645607d889c5e402dbb4d51049b9c/statsmodels-0.8.0-2.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,csv,car,Duncan.csv.zip"
Skipping broken link "~/.cache/edm/packages/8b/8df08a725117b8d62702fa63888f9ea96645607d889c5e402dbb4d51049b9c/statsmodels-0.8.0-2.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,datasets.csv.zip"
Skipping broken link "~/.cache/edm/packages/8b/8df08a725117b8d62702fa63888f9ea96645607d889c5e402dbb4d51049b9c/statsmodels-0.8.0-2.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,doc,car,rst,Duncan.rst.zip"
Skipping broken link "~/.cache/edm/packages/97/b41e8af02f727c02e989d8c7aaa8b3dd5ace895dbed551255c4c139fc468c1/enable-4.6.0-8.egg/enable/images.zip"
Skipping broken link "~/.cache/edm/packages/b7/f470df7779d5cdd243ec80d24dd30b0398e453d167d010b1d225a5a651a7c8/pyproj-1.9.4-2.egg/pyproj/data/proj-datumgrid-1.5.zip"
Skipping broken link "~/.cache/edm/packages/d3/5442b5eb8a3ea8720369f6693cfec1339098333047fd1390ae6c32b8b733dc/mayavi-4.5.0-4.egg/tvtk/tvtk_classes.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/03/468968d57d86ad6b713a23c111111ee9f729a1f3f27b28030131238fd07e8b/enable-4.7.1-2.egg/enable/images.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/0c/973bfbc153114e8009f1112f0b3386efcf60aec9866ad01c7002bf59c82ad6/pandas-0.23.1-1.egg/pandas/tests/io/json/data/tsframe_v012.json.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/0c/973bfbc153114e8009f1112f0b3386efcf60aec9866ad01c7002bf59c82ad6/pandas-0.23.1-1.egg/pandas/tests/io/parser/data/salaries.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/0c/973bfbc153114e8009f1112f0b3386efcf60aec9866ad01c7002bf59c82ad6/pandas-0.23.1-1.egg/pandas/tests/io/parser/data/utf16_ex_small.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/34/34464d58efc74c8a2defe5ab405d61100a902d9b933e8ce9e177781cb80ca8/enable-4.7.2-1.egg/enable/images.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/64/024e89c78085d21d70a03dc9e44b4c2eb248136bfc9bad1293beb4f3668f80/statsmodels-0.8.0-5.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,csv,car,Duncan.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/64/024e89c78085d21d70a03dc9e44b4c2eb248136bfc9bad1293beb4f3668f80/statsmodels-0.8.0-5.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,datasets.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/64/024e89c78085d21d70a03dc9e44b4c2eb248136bfc9bad1293beb4f3668f80/statsmodels-0.8.0-5.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,doc,car,rst,Duncan.rst.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/69/21fba32132ba63da3f23e602864be3410c02bbb02675a56a7238d32eb094bd/traitsui-6.0.0-1.egg/traitsui/image/library/icons.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/69/21fba32132ba63da3f23e602864be3410c02bbb02675a56a7238d32eb094bd/traitsui-6.0.0-1.egg/traitsui/image/library/std.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/6a/d09d96a2c1782468884a03837e4a0d59a083f34037f3332106db77383ef968/statsmodels-0.8.0-6.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,csv,car,Duncan.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/6a/d09d96a2c1782468884a03837e4a0d59a083f34037f3332106db77383ef968/statsmodels-0.8.0-6.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,datasets.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/6a/d09d96a2c1782468884a03837e4a0d59a083f34037f3332106db77383ef968/statsmodels-0.8.0-6.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,doc,car,rst,Duncan.rst.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/75/78d80e79577f0aec332145c17df540921cdc324fc33f7eb7ad352c9d6dbea7/statsmodels-0.8.0-3.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,csv,car,Duncan.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/75/78d80e79577f0aec332145c17df540921cdc324fc33f7eb7ad352c9d6dbea7/statsmodels-0.8.0-3.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,datasets.csv.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/75/78d80e79577f0aec332145c17df540921cdc324fc33f7eb7ad352c9d6dbea7/statsmodels-0.8.0-3.egg/statsmodels/datasets/tests/raw.github.com,vincentarelbundock,Rdatasets,master,doc,car,rst,Duncan.rst.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/be/6727fc4fc031a60849343244c3e51586ce5c2a967af81c218b89dc048d5f9d/mayavi-4.5.0-5.egg/tvtk/tvtk_classes.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/c1/4f6191b3cfff0f026ff08e6e084ca300f98d2fba224f4dbe4c6c79859aa4d3/pyface-6.0.0-1.egg/pyface/image/library/icons.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/c1/4f6191b3cfff0f026ff08e6e084ca300f98d2fba224f4dbe4c6c79859aa4d3/pyface-6.0.0-1.egg/pyface/image/library/std.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/cf/54faadbda0fb2eec1a591a33f92991235559f7c39f551a1dc492b3835cb518/mayavi-4.5.0-6.egg/tvtk/tvtk_classes.zip"
Skipping broken link "~/.local/share/canopy/edm/canopy-platform-cache/packages/f3/c15dcfc01e65e1e74eef7a25a3e5b970b34b727dc44dfcc095ee5e3bc3e890/enable-4.7.2-2.egg/enable/images.zip"
Auto-excluding ~/.local/share/canopy/edm/envs/User
Auto-excluding ~/.local/share/canopy/edm/envs/mika_prepro
Auto-excluding ~/.local/share/canopy/edm/envs/python_3-5
(node:94823) UnhandledPromiseRejectionWarning: Libzip Error: Not a zip archive
at Q.makeLibzipError (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ZipFS.js:149:29)
at new Q (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ZipFS.js:121:28)
at getZipSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ZipOpenFS.js:784:28)
at g.makeCallSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ZipOpenFS.js:665:21)
at g.existsSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ZipOpenFS.js:232:21)
at a.existsSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ProxiedFS.js:71:28)
at o.existsSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/node_modules/@yarnpkg/fslib/lib/ProxiedFS.js:71:28)
at T.existsSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/src/common/fileSystem.ts:213:23)
at t.PyrightFileSystem.existsSync (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/src/pyrightFileSystem.ts:63:29)
at _configOptions.autoExcludeVenv.i.some.t (~/anaconda3/envs/python37/lib/node_modules/pyright/dist/pyright-internal/src/analyzer/service.ts:1027:53)
(node:94823) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:94823) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
$
@jingxlim Does you install pyright in conda env? I think you should try to add its location to PATH. Or install globally should be a more simpler choice, as (executable-find "pyright" t)
cannot find pyright in your env.
Yes, I did install pyright
in my conda env. Perhaps I mistook how pyright works, but I assumed that pyright needs to be aware of the packages installed in a certain environment and therefore needs to be installed in an environment where all I packages I use/need are installed.
In any case, I added my conda env's bin dir to $PATH
and now emacs can find pyright!
"~/anaconda3/envs/python37/bin/pyright"
I'm still encountering problems with lsp-mode though. Same error as before.
By the way, should .dir-locals.el
contain a tramp command? i.e. with /ssh:[remote]:
((python-mode . ((eval . (lsp-register-custom-settings
'(("python.pythonPath" "/ssh:[remote]:~/anaconda3/envs/python37/bin/python"
"python.venvPath" "/ssh:[remote]:~/anaconda3/envs/python37")))))))
Perhaps I mistook how pyright works, but I assumed that pyright needs to be aware of the packages installed in a certain environment and therefore needs to be installed in an environment where all I packages I use/need are installed.
config options venv
and venvPath
are enough for specifying the virtual environment to use.
I don't know why there is no *lsp-log*
, but without further information, it is hard to know what went wrong. Four suggestions: 1. try to make it work locally; 2. install pyright globally; 3. try on toy project; 4. try on the base env.
@tshu-w, I was able to do (1) and (3) without conda. I installed pyright on my local system and was able to start a server with a local python file. Three new buffers were created: *lsp-log*, *pyright*, and *pyright::stderr*.
However, the problem persisted remotely.
I was not able to do (2) because I don't have sudo on my remote system leading to permission errors.
I guess the next step is to figure out why the *lsp-log* buffer isn't created when viewing a tramp python file. Any ideas?
Sorry, no more ideas. The last one to check https://github.com/emacs-lsp/lsp-pyright/issues/10#issuecomment-780739945
Okay, after consulting with @yyoncho on lsp-mode's discord, I found out that lsp-clients
is obsolete. Instead he advised using either lsp-mode
or lsp-pyright
. Therefore, I switched to using after! lsp-pyright
instead of after! lsp-clients
. The following config worked for me on doom-emacs, for anyone who's wondering if this was resolved. Thanks also @tshu-w for the help and @mjlbach for the original config!
(setq enable-remote-dir-locals t)
(setq enable-local-variables :all)
(after! tramp
(add-to-list 'tramp-remote-path 'tramp-own-remote-path))
(use-package! lsp-mode
:commands lsp
:hook
(python-mode . lsp))
(after! lsp-pyright
(setq lsp-log-io t)
(setq lsp-pyright-use-library-code-for-types t)
(setq lsp-pyright-diagnostic-mode "workspace")
(lsp-register-client
(make-lsp-client
:new-connection (lsp-tramp-connection (lambda ()
(cons "pyright-langserver"
lsp-pyright-langserver-command-args)))
:major-modes '(python-mode)
:remote? t
:server-id 'pyright-remote
:multi-root t
:priority 3
:initialization-options (lambda () (ht-merge (lsp-configuration-section "pyright")
(lsp-configuration-section "python")))
:initialized-fn (lambda (workspace)
(with-lsp-workspace workspace
(lsp--set-configuration
(ht-merge (lsp-configuration-section "pyright")
(lsp-configuration-section "python")))))
:download-server-fn (lambda (_client callback error-callback _update?)
(lsp-package-ensure 'pyright callback error-callback))
:notification-handlers (lsp-ht ("pyright/beginProgress" 'lsp-pyright--begin-progress-callback)
("pyright/reportProgress" 'lsp-pyright--report-progress-callback)
("pyright/endProgress" 'lsp-pyright--end-progress-callback))))
)
This is still working sub-optimally for me as I have to run M-x lsp-workspace-restart
2 times before the scan starts and I get completions. I wonder why this is the case...
aha, I don't even know lsp-clients
.
This is still working sub-optimally for me as I have to run
M-x lsp-workspace-restart
2 times before the scan starts and I get completions. I wonder why this is the case...
As mention above, lsp currently not work well with tramp, you should upgrade tramp and change lsp-tramp-connection
by yourself.
@tshu-w, I see! Is my current lsp-tramp-connection
, as shown above (copied from OP), sufficient?
I think the above pr link https://github.com/emacs-lsp/lsp-mode/pull/2531 has made it clear that you need to modify the lsp-tramp-connection function yourself and upgrade the tramp. You did not show the modified lsp-tramp-connection
above.
(defun lsp-tramp-connection (local-command &optional generate-error-file-fn)
"Create LSP stdio connection named name.
LOCAL-COMMAND is either list of strings, string or function which
returns the command to execute."
(defvar tramp-connection-properties)
;; Force a direct asynchronous process.
(when (file-remote-p default-directory)
(add-to-list 'tramp-connection-properties
(list (regexp-quote (file-remote-p default-directory))
"direct-async-process" t)))
(list :connect (lambda (filter sentinel name environment-fn)
(let* ((final-command (lsp-resolve-final-function
local-command))
(_stderr (or (when generate-error-file-fn
(funcall generate-error-file-fn name))
(format "/tmp/%s-%s-stderr" name
(cl-incf lsp--stderr-index))))
(process-name (generate-new-buffer-name name))
(process-environment
(lsp--compute-process-environment environment-fn))
(proc (make-process
:name process-name
:buffer (format "*%s*" process-name)
:command final-command
:connection-type 'pipe
:coding 'no-conversion
:noquery t
:filter filter
:sentinel sentinel
:file-handler t)))
(cons proc proc)))
:test? (lambda () (-> local-command lsp-resolve-final-function
lsp-server-present?))))
I wanted to thank the OP for their remote pyright setup code, which is working well. I came up with a few workflow simplifications that might be useful. In terms of paths/virtual environments, if you are frequently using similar remote venvs, there is the simple strategy of adding to your .ssh/config
file something like:
Host host-venv
HostName my.host.name
RequestTTy force
RemoteCommand bash --init-file .bash_venv
where the remote file .bash_venv
contains . path/to/venv/bin/activate
. Then always visit files you intend to use with that venv as /ssh:host-venv:file.py
. You could setup a few this way as well.
Another convenience can be had with a small addition like:
(defun my/python-shell-remote-name (name)
(if-let ((buffer-file-name) (host (file-remote-p buffer-file-name 'host)))
(format "%s<%s>" name host)
name))
(advice-add #'python-shell-get-process-name
:filter-return #'my/python-shell-remote-name)
This gives you a buffer name like *Python<host-venv>*
when you invoke run-python
(C-c C-p
).
I've seen several comments on the github issues asking about tramp, python virtual environments and lsp-mode for python. It's currently possible-ish with a couple hacks. For pyright (for example), the following launches uses the standard python interpreter
/usr/bin/python
To accomodate virtualenvs, I added some additional initialization code to read the virtualenvironment off of pyvenv, prune the tramp path, and pass it to the server.
This could be cleaner, and there isn't a unified way with pyenv-mode and poetry.el not officially supporting virtualenvs over TRAMP. I have a version of virtualenv support for pyvenv/poetry.el, but maybe it would make sense to coordinate with them upstream.