Open svoop opened 3 weeks ago
Hi. Unfortunately, only native extensions support this option. To workaround that the Ruby extension uses the current project shell environment to apply many things like activating the correct Ruby version manager or spawning direnv
like this:
pub fn language_server_command(
&mut self,
language_server_id: &LanguageServerId,
worktree: &zed::Worktree,
) -> Result<zed::Command> {
let binary = self.language_server_binary(language_server_id, worktree)?;
Ok(zed::Command {
command: binary.path,
args: binary.args.unwrap_or_default(),
env: worktree.shell_env(), // Use the project shell environment
})
}
Is this setting required for direnv
based setups? I stopped using direnv
some time ago so I could miss something for sure. Thanks.
To workaround that the Ruby extension uses the current project shell environment
Which makes sense. But maybe there's a timing issue with direnv
(and possibly other similar tools) as mentioned here?
Is this setting required for
direnv
based setups?
At least it appears to solve this timing issue for the ruby-analyzer
LSP, too bad this is no option for non-native extensions.
(With "native extension" you mean extensions built right into Zed, right?)
The symptoms I see right now are: I can get the right environment to load for the terminal if and only if I open Zed with zed myproject
. It does not work with cd myproject; zed .
Either way, the ruby-lsp
binary wasn't found.
However, I've executed ruby-lsp --doctor
in the terminal and now I see a different error logged when Zed opens. I'll investigate this further...
To workaround that the Ruby extension uses the current project shell environment
Which makes sense. But maybe there's a timing issue with
direnv
(and possibly other similar tools) as mentioned here?Is this setting required for
direnv
based setups?At least it appears to solve this timing issue for the
ruby-analyzer
LSP, too bad this is no option for non-native extensions.(With "native extension" you mean extensions built right into Zed, right?)
The symptoms I see right now are: I can get the right environment to load for the terminal if and only if I open Zed with
zed myproject
. It does not work withcd myproject; zed .
Either way, theruby-lsp
binary wasn't found.However, I've executed
ruby-lsp --doctor
in the terminal and now I see a different error logged when Zed opens. I'll investigate this further...
Aha, I will check if direnv
works fine. What Ruby version manager should I use with it in my tests?
Aha, I will check if direnv works fine. What Ruby version manager should I use with it in my tests?
None, direnv
itself can manage the Ruby. I'll send you my setup, however, please bear with me for a day or two... I have to digest the new world order today and then would like to fix how I use binstubs. There is some chance that this is causing the troubles or at least making them worse and I don't want to send you on a wrong path.
One question though: When the Ruby extension calls ruby-lsp
or other binaries, I assume it's doing so with bundle exec
wrapped around?
My use of binstubs is not relevant, the problem is exactly the same on a vanilla macOS machine. I've compiled the steps to reproduce it for you in this Gist:
https://gist.github.com/svoop/b7665ce3f3f7b4fe28d72b8bd66e1bfe
(This setup uses direnv
as the Ruby version manager and does not need another one like rbenv
or chruby
.)
The last step in the Gist opens a small FOSS project of mine in Zed. When editing any Ruby source file, Zed logs:
Language server error: ruby-lsp
ruby-lsp must be installed manually. Install it with `gem install ruby-lsp`.
-- stderr --
When I open a terminal within Zed, the direnv
environment is apparently loaded.
~The ruby-lsp
binary is available, but it throws a funky error due to the explicit versions requested. Not sure whether this is also what's behind the "Language server error" above though: Ruby LSP> Running bundle install for the custom bundle. This may take a while... Command: (bundle _2.5.16_ check || bundle _2.5.16_ install) 1>&2 Could not find command "_2.5.16_".
~
Update: After running ruby-lsp
once in iTerm (not the terminal of Zed), the LSP bundle apparently works and the output is now both in iTerm and Zed terminal:
ruby-lsp --debug
DEBUGGER: Debugger can attach via UNIX domain socket (/var/folders/85/nz5_r759487f0vy2wj6q51qw0000gn/T/ruby-debug-sock-501/ruby-debug-username-67887)
@vitallium Ping. (Not to push, just forgot to mention you in my two previous comments, so you might not have been notified.)
One question though: When the Ruby extension calls ruby-lsp or other binaries, I assume it's doing so with bundle exec wrapped around?
No, it does not do that. For this option, there are two possible ways:
Thanks for providing a test case. I'll check it and come back with results.
@svoop I tried to replicate your setup but there is something wrong with it. I used a clean VM with macOS Sonoma. For some reason, the use_ruby
function failed to find the installed Ruby 3.3.5 version:
Here is the output when I ran bundle install
command:
vslobodin@Vitalys-Virtual-Machine notam % bundle
ruvFetching gem metadata from https://rubygems.org/...........y
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Bundler could not find compatible versions for gem "ruby":
In gems.rb:
ruby
notam was resolved to 1.1.5, which depends on
ruby (>= 3.0.0)
Could not find gem 'ruby (>= 3.0.0)', which is required by gem 'notam', in any of the relevant sources:
the local ruby installation
The ruby --version
outputs the system Ruby version:
vslobodin@Vitalys-Virtual-Machine notam % ruby --version
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin23]
So the direnv status
fails to load the Ruby version:
vslobodin@Vitalys-Virtual-Machine notam % direnv status
direnv exec path /opt/homebrew/bin/direnv
DIRENV_CONFIG /Users/vslobodin/.config/direnv
bash_path /opt/homebrew/opt/bash/bin/bash
disable_stdin false
warn_timeout 5s
whitelist.prefix []
whitelist.exact map[]
No .envrc or .env loaded
Found RC path /Users/vslobodin/dev/notam/.envrc
Found watch: ".envrc" - 2024-11-14T17:16:26+01:00
Found watch: "../../.local/share/direnv/allow/fac619f7fe58cf16745de69ec71a336dbefcd3e5680659cf2fb5cfe2737be77b" - 2024-11-14T17:13:19+01:00
Found watch: "../../.local/share/direnv/deny/f8dc79d4179321f0fb0f586bd7ec64715fe8cf4e52a749798708c7be41efd1e2" - 1970-01-01T01:00:00+01:00
Found RC allowed 0
Found RC allowPath /Users/vslobodin/.local/share/direnv/allow/fac619f7fe58cf16745de69ec71a336dbefcd3e5680659cf2fb5cfe2737be77b
But I have installed ruby-3.3.5
:
vslobodin@Vitalys-Virtual-Machine notam % ls ~/.rubies
ruby-3.3.5
Can you please check this? Perhaps there is something wrong with the provided instructions? Thanks!
Can you please check this? Perhaps there is something wrong with the provided instructions? Thanks!
Totally possible since I've kinda grown this on my old Mac. What do you use to spool up virtual Macs, Parallels?
What do you use to spool up virtual Macs, Parallels?
UTM (and sometimes VMware)
What happens when you open a new terminal and then cd notam
? Does direnv actually jump into action and output something like:
Switching to ruby-3.3.5
direnv: export +BUNDLE_BIN +CPATH (...)
If not, then please check whether the file notam/.envrc
exists and contains use ruby
. Also, when you cd notam
for the first time, you have to direnv allow
– as well as whenever you change something in notam/.envrc
.
Nope, nothing happens. I checked the .envrc
file and so on.
UPD
As always, rebooting the virtual machine helped! direnv
works now.
So, starting the Zed editor from the Dock gives me the following output from starting the ruby-lsp
:
Language server error: ruby-lsp
oneshot canceled
-- stderr--
Ruby LSP> Skipping custom bundle setup since /Users/vslobodin/dev/notam/.ruby-lsp/gems.locked already exists and is up to date
Ruby LSP> Running bundle install for the custom bundle. This may take a while...
Ruby LSP> Command: (bundle _2.5.16_ check || bundle _2.5.16_ install) 1>&2
Could not find command "_2.5.16_".
Could not find command "_2.5.16_".
Ruby LSP> Running bundle install failed. Trying to re-generate the custom bundle from scratch
Ruby LSP> Running bundle install for the custom bundle. This may take a while...
Ruby LSP> Command: (bundle _2.5.16_ check || bundle _2.5.16_ install) 1>&2
Could not find command "_2.5.16_".
Could not find command "_2.5.16_".
Could not find command "_2.5.16_".
This is a known issue for ruby-lsp
- https://github.com/Shopify/ruby-lsp/issues/2731
This is a known issue for ruby-lsp - https://github.com/Shopify/ruby-lsp/issues/2731
Ah, should have researched on ruby-lsp issues myself, sorry about that. The issue is closed and the merge was made 3 weeks ago, so 0.21.3 (released 9 days ago) should contain the fix. But when I launch ruby-lsp in either the terminal app or the Zed terminal, I still get the could not find command "_2.5.16_"
errors, guess I have to take that up with the authors of ruby-lsp.
I'll dig in some more tomorrow, have to fly to the movies now. Thanks a lot for all your work, I really appreciate it!
@vitallium Okay, tried the following in the Zed terminal:
% rm -rf .direnv/bin .ruby-lsp
% which ruby-lsp
/Users/myself/.gem/ruby/3.3.0/bin/ruby-lsp
% gem list | grep ruby-lsp
ruby-lsp (0.21.3)
% ruby-lsp --debug
Ruby LSP> Running bundle install for the custom bundle. This may take a while...
Ruby LSP> Command: (bundle _2.5.4_ check || bundle _2.5.4_ install) 1>&2
Resolving dependencies...
The Gemfile's dependencies are satisfied
DEBUGGER: Debugger can attach via UNIX domain socket (/var/folders/85/nz5_r759487f0vy2wj6q51qw0000gn/T/rdbg-501/rdbg-72537)
^C
% ruby-lsp --debug
Ruby LSP> Skipping custom bundle setup since /Users/myself/notam/.ruby-lsp/gems.locked already exists and is up to date
Ruby LSP> Running bundle install for the custom bundle. This may take a while...
Ruby LSP> Command: ((bundle _2.5.4_ check && bundle _2.5.4_ update ruby-lsp) || bundle _2.5.4_ install) 1>&2
The Gemfile's dependencies are satisfied
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Bundler attempted to update ruby-lsp but its version stayed the same
Bundle updated!
Could not find command "_2.5.4_".
% which ruby-lsp
/Users/myself/notam/.direnv/bin/ruby-lsp
% ruby-lsp --debug
DEBUGGER: Debugger can attach via UNIX domain socket (/var/folders/85/nz5_r759487f0vy2wj6q51qw0000gn/T/rdbg-501/rdbg-72655)
^C
Apparently, on the second launch of ruby-lsp
, it attempts an update and struggles. But that's a minor issue and the third as well as subsequent calls work again.
Starting Zed with zed notam
, however, ruby-lsp
doesn't launch and the log reads:
2024-11-15T19:36:35.382445+01:00 [INFO] attempting to start language server "ruby-lsp", path: "/Users/myself/notam", id: 6
2024-11-15T19:36:35.399799+01:00 [ERROR] Failed to start language server "ruby-lsp": ruby-lsp must be installed manually. Install it with `gem install ruby-lsp`.
2024-11-15T19:36:35.399945+01:00 [ERROR] server stderr: ""
The log also dumps the PATH it uses with "project environment variables from CLI". And it is different from the PATH set in the Zed terminal. Diffing the two, the following paths are only present in the Zed terminal (newlines added after colons for readability):
/Users/myself/notam/bin:
/Users/myself/notam/.direnv/bin:
/Users/myself/.gem/ruby/3.3.0/bin:
/Users/myself/notam/.direnv/bin:
/Users/myself/notam/.direnv/ruby/bin:
/Users/myself/.rubies/ruby-3.3.5/bin:
These are the paths added by direnv and without them, ruby-lsp
is not found.
@vitallium Any luck replicating this problem yet?
The LSP may be installed in different locations depending on whether and which Ruby version manager you use. To leverage the similar problem for Rust, the built-in Rust support has recently ntroduced a
path_lookup
setting, here's the commit:https://github.com/zed-industries/zed/pull/12418
It's used as follows:
As suggested in a thread on
direnv
support in Zed, it appears to be desirable for all LSP setups to implement this setting.How about adding a similar feature to
ruby-lsp
and the other supported LSPs for Ruby?(I'd do a PR, but I haven't written a single line of Rust in my life so far, you don't want me to fiddle with your code.)