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

Allow PATH lookup #11

Open
svoop opened this issue Nov 5, 2024 · 17 comments
Open

Allow PATH lookup #11

svoop opened this issue Nov 5, 2024 · 17 comments

Comments

@svoop
Copy link

svoop commented Nov 5, 2024

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:

zed-industries/zed#12418

It's used as follows:

{
  "lsp": { 
    "rust-analyzer": { 
      "binary": { 
        "path_lookup": true 
      } 
    } 
  }
}

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?

{
  "lsp": { 
    "ruby-lsp": { 
      "binary": { 
        "path_lookup": true 
      } 
    } 
  }
}

(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.)

@vitallium
Copy link
Collaborator

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.

@svoop
Copy link
Author

svoop commented Nov 5, 2024

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...

@vitallium
Copy link
Collaborator

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...

Aha, I will check if direnv works fine. What Ruby version manager should I use with it in my tests?

@svoop
Copy link
Author

svoop commented Nov 6, 2024

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?

@svoop
Copy link
Author

svoop commented Nov 6, 2024

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)

@svoop
Copy link
Author

svoop commented Nov 13, 2024

@vitallium Ping. (Not to push, just forgot to mention you in my two previous comments, so you might not have been notified.)

@vitallium
Copy link
Collaborator

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:

  1. Use a binstub
  2. Specify the binary manually, i.e., https://zed.dev/docs/languages/ruby#setting-up-solargraph

@vitallium
Copy link
Collaborator

Thanks for providing a test case. I'll check it and come back with results.

@vitallium
Copy link
Collaborator

vitallium commented Nov 14, 2024

@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!

@svoop
Copy link
Author

svoop commented Nov 14, 2024

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?

@vitallium
Copy link
Collaborator

What do you use to spool up virtual Macs, Parallels?

UTM (and sometimes VMware)

@svoop
Copy link
Author

svoop commented Nov 14, 2024

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.

@vitallium
Copy link
Collaborator

vitallium commented Nov 14, 2024

Nope, nothing happens. I checked the .envrc file and so on.

UPD

As always, rebooting the virtual machine helped! direnv works now.

@vitallium
Copy link
Collaborator

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 - Shopify/ruby-lsp#2731

@svoop
Copy link
Author

svoop commented Nov 14, 2024

This is a known issue for ruby-lsp - Shopify/ruby-lsp#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!

@svoop
Copy link
Author

svoop commented Nov 15, 2024

@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.

@svoop
Copy link
Author

svoop commented Nov 25, 2024

@vitallium Any luck replicating this problem yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants