Skip to content

VS Code: Add customBinaryPath option #3386

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

palkan
Copy link

@palkan palkan commented Apr 10, 2025

Motivation

This option allows to provide any compatible binary to be used as ruby-lsp exec. This is especially useful for containerized development with VS Code running on the host machine (i.e., not using Dev Containers or Remote Containers). A typical use case is the applications using dip (and ruby-on-whales) (see #2919). However, the ability to customize the binary path has many more potential applications.

Motivation continues...

I've been using a similar approach with Zed for a while (it already provides this option). The trick is to use a thin Bash wrapper to run ruby-lsp anywhere. Mine looks as follows:

#!/bin/bash

cd $(dirname $0)/..

dip ruby-lsp $@

That's it.

With this change, we can configure rubyLsp.customBinaryPath to point to a custom executable (say, ".dockerdev/ruby-lsp"), and benefit from LSP features even without having Ruby LSP (and even Ruby) installed locally (let me omit some Docker-specific tricks used to make it work, not relevant to the proposal).

Implementation

  • Added new configuration option to package.json: customBinaryPath
  • Updated client.ts to use the new option if present to generate commands configuration.

Automated Tests

None. Couldn't find any tests for similar functionality (commands configuration). Would love to have some guidance here.

Manual Tests

Packaged and installed the forked version locally and verified that LSP works.

This option allows to provide any compatible binary to be used as `ruby-lsp` exec
@palkan palkan requested a review from a team as a code owner April 10, 2025 00:12
Copy link

graphite-app bot commented Apr 10, 2025

How to use the Graphite Merge Queue

Add the label graphite-merge to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@palkan
Copy link
Author

palkan commented Apr 10, 2025

I have signed the CLA!

@willtcarey
Copy link

This should resolve #2223 with the same motivation and ideas here

@palkan
Copy link
Author

palkan commented May 3, 2025

Hey @vinistock,

Sorry for pushing, but it would be nice to at least know if there is something the team considers to be a good addition (and, thus, we can expect it soon) or not at all. Thanks.

@vinistock
Copy link
Member

Thanks for the PR. Would supporting running the language server through sockets solve this use case?

Connecting to the LSP via sockets is standardized in the spec. If that solves the use cases, I would rather we implemented that rather than allowing customizing the executable.

The launching of the LSP ends up being the most critical part of our integration because we need to fully replicate the user's environment with the contributions of their version manager + bundler. I'm still not satisfied with the level of robustness of our launching and I'm afraid that allowing people to configure whatever executable they want could potentially build us into a corner where we cannot change the main ruby-lsp executable without a major breaking change.

Before committing to a decision, I'd also like to understand how other language servers solve this problem. What does Rust Analyzer do (or any other LSP)? As far as I know, there's no way to change its executable.

@palkan
Copy link
Author

palkan commented May 15, 2025

Would supporting running the language server through #1782 solve this use case?

Don't think so. The problem is not with accessing the language server but launching it.

The launching of the LSP ends up being the most critical part of our integration because we need to fully replicate the user's environment with the contributions of their version manager + bundler.

...Or let the user take care of the replication. For smaller projects, having ruby-lsp automatically set up itself and just work is great, I love it. But as soon as development environment becomes more complicated (like in our case with Docker), the magic no longer works.

I'm afraid that allowing people to configure whatever executable they want could potentially build us into a corner where we cannot change the main ruby-lsp executable without a major breaking change.

This is definitely an advanced option and must be used with caution. And it's the responsibility of the end user to comply with the ruby-lsp interface, not vice versa.

...how other language servers solve this problem

That seems more about editor plugins then LSPs.

Zed, for example, allows customizing the binary path for both Ruby LSP and Rust Analyzer (and, I think, others as well).
Solargaph's VS Code extension has the commandPath setting. And Rust VS Code has the rust-analyzer.server.path.

@palkan
Copy link
Author

palkan commented Jun 11, 2025

Hey @vinistock,

Have you had a chance to look at my previous comment?

@dsager
Copy link

dsager commented Jun 12, 2025

...how other language servers solve this problem

That seems more about editor plugins then LSPs.

The VSCode extension for rubocop also allows you to set a custom command, adding the to the following configuration works well:

{
  "rubocop.commandPath": "docker-compose exec my-app-name bundle exec rubocop"
}

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

Successfully merging this pull request may close these issues.

None yet

4 participants