疑難排解

Ruby LSP 如何啟動

Ruby LSP 擴充功能與其他 VS Code 擴充功能一樣,在 VS Code 的 NodeJS 執行環境中執行。這表示在您的 Shell 中正確設定的環境變數,可能不會存在於 NodeJS 程序中。為了使用與您的專案相同的 Ruby 版本執行 LSP 伺服器,我們需要正確設定這些環境變數,這會透過調用您的 Ruby 版本管理器來完成。

此擴充功能使用您 Shell 的互動模式執行命令,以便自動選取在 ~/.zshrc 等檔案中設定的版本管理器。然後,此命令會將環境資訊匯出為 JSON,以便我們將其注入 NodeJS 程序中,並適當地設定 Ruby 版本和 gem 安裝路徑。

例如,使用 rbenv 作為版本管理器的 zsh 啟動腳本會類似如下

# Invoke zsh using interactive mode (loads ~/.zshrc) to run a single command
# The command is `rbenv exec ruby`, which automatically sets all relevant environment variables and selects the
# specified Ruby version
# We then print the activated environment as JSON. We read that JSON from the NodeJS process to insert the needed
# environment variables in order to run Ruby correctly
/bin/zsh -ic 'rbenv exec ruby -rjson -e "puts JSON.dump(ENV.to_h)"'

啟用 Ruby 版本後,我們接著啟動伺服器 gem (ruby-lsp)。為了避免使用者在其 Gemfile 中包含 ruby-lsp,我們會在您專案內的 .ruby-lsp 目錄下建立一個組合套件

常見問題

使用者在啟用期間通常會遇到幾個主要問題來源:過時的版本、Shell 問題或 Bundler 相關問題。

過時的版本

如果使用 VS Code,擴充功能版本與伺服器(ruby-lsp gem)版本是不同的。您可以在狀態中心查看伺服器版本。

在大多數情況下,伺服器 gem 會自動更新。您也可以使用 VS Code 中的「更新語言伺服器 gem」命令觸發手動更新。

您也可以嘗試使用命令列執行更新:BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle update ruby-lsp

如果您使用任何附加 gem,例如 ruby-lsp-rspec,則 ruby-lsp 也會出現在您的 Gemfile.lock 中,而且過時的附加元件可能會阻止 ruby-lsp 更新。

無法更新 ruby-lsp gem 的另一個可能情況是,其執行階段相依性之一受到應用程式中另一個 gem 的限制。例如,Ruby LSP 依賴 RBS v3。如果另一個 gem 將 RBS 的版本限制為較舊的版本,則無法使用較新版本的 Ruby LSP。

Ruby LSP 的 3 個執行階段相依性為 rbsprismsorbet-runtime。如果其中任何一個受到應用程式的限制,Ruby LSP 可能會無法更新。

執行 BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle outdated 可能有助於了解哪些受到限制。

Shell 問題

當擴充功能調用 Shell 並載入其設定檔(~/.zshrc~/.bashrc 等)時,它很容易受到 Shell 或其外掛程式與 NodeJS 程序互動方式所造成的問題影響。例如

  • 某些外掛程式會完全重新導向 stderr 管道以實作其功能(已在 Ruby LSP 端透過 https://github.com/Shopify/vscode-ruby-lsp/pull/918 修正)
  • 如果某些外掛程式偵測到 Shell 程序未附加 UI,則會立即失敗或陷入無窮迴圈。在這種情況下,無法從 Ruby LSP 端進行修正,因為 NodeJS 調用的 Shell 永遠不會有 UI

此外,有些使用者會遇到 VS Code 選取錯誤 Shell 的問題,不尊重 SHELL 環境變數。這通常會導致選取 /bin/sh 而不是您實際的 Shell。如果您遇到此問題,請嘗試

  • 將 VS Code 更新到最新版本
  • 完全關閉 VS Code,並使用 code . 從終端機啟動它(而不是從啟動圖示開啟 VS Code)

關於此問題的更多資訊,請參閱 https://github.com/Shopify/vscode-ruby-lsp/issues/901。

Bundler 問題

首先,請確定您使用的是最新版本的 Bundler(執行 bundle update --bundler)。

如果擴充功能成功啟動 Ruby 環境,在嘗試組合組合套件以執行伺服器 gem 時,仍然可能會失敗。這可能是常見的 Bundler 問題,例如因為版本需求衝突而無法滿足相依性,或者可能是設定問題。

例如,如果專案將其 linter/formatter 放在選用的 Gemfile 群組中,且該群組在 Bundler 設定中被排除,則 Ruby LSP 將無法看到這些 gem。

# Gemfile

# ...

# If Bundler is configured to exclude this group, the Ruby LSP will not be able to find `rubocop`
group :optional_group do
  gem "rubocop"
end

如果您遇到 Bundler 相關問題,請仔細檢查您的全域和專案特定設定,以檢查是否有任何阻止伺服器啟動的因素。您可以使用以下命令列印您的 Bundler 設定:

bundle config

儲存時格式化對話方塊不會消失

當 VS Code 要求格式化文件時,會在傳送要求幾秒後開啟一個顯示進度的對話方塊,一旦伺服器回應格式化結果,就會關閉它。

如果您看到對話方塊沒有消失,這很可能表示格式化花費很長時間或卡住。這很可能表示伺服器當機或進入損毀狀態,而根本沒有回應任何要求,這表示對話方塊永遠不會消失。

這通常是伺服器中的錯誤所導致。它應該始終以優雅的方式失敗,而不會進入損毀狀態,以至於無法回應來自編輯器的新要求。如果您遇到這種情況,請在此處提交錯誤報告,包括導致伺服器卡住的步驟。

缺少的功能

如果您發現某些功能(例如格式化)可以運作,但其他功能(例如前往定義)不能運作,並且正在使用使用 Sorbet 的程式碼庫,則這可能表示Sorbet LSP 未執行。為了避免重複/衝突的行為,Ruby LSP 會在偵測到 Sorbet 程式碼庫時停用某些功能,其目的是讓 Sorbet 提供更高的準確性。

Gem 安裝位置和權限

為了啟動 Ruby LSP 伺服器,必須安裝 ruby-lsp gem。而且為了自動索引您專案的相依性,也必須安裝它們,以便我們可以讀取、剖析和分析其原始程式碼檔案。ruby-lsp gem 是透過 gem install 安裝(使用 RubyGems)。專案相依性是透過 bundle install 安裝(使用 Bundler)。

如果您使用非預設路徑安裝 gem,請記住 RubyGems 和 Bundler 需要個別設定才能實現此目的。

例如,如果您設定 BUNDLE_PATH 指向 vendor/bundle,以便 gem 安裝在與您的專案相同的目錄中,bundle install 會自動選取並將它們安裝在正確的位置。但是 gem install 不會,因為它需要不同的設定才能實現此目的。

您可以使用 ~/.gemrc 檔案,為 RubyGems 套用您偏好的安裝位置。在該檔案中,您可以決定使用 --user-install 安裝,或使用 --install-dir 選取特定的安裝目錄。

gem: --user-install
# Or
gem: --install-dir /my/preferred/path/for/gem/install

其中一個這種情況很有用的例子是,如果使用者沒有預設 gem 安裝目錄的權限,而 gem install 失敗。例如,在某些 Linux 發行版上使用系統 Ruby 時。

使用非預設的 gem 安裝路徑可能會導致與版本管理器的其他整合問題。例如,對於 Ruby 3.3.1,預設的 GEM_HOME~/.gem/ruby/3.3.0(沒有版本的修補程式部分)。但是,chruby

(以及其他可能的版本管理器)會覆寫 GEM_HOME 以包含版本修補程式,導致 ~/.gem/ruby/3.3.1。當您使用 gem install --user-install 安裝 gem 時,RubyGems 會忽略 GEM_HOME 覆寫,並將 gem 安裝在 ~/.gem/ruby/3.3.0 中。這會導致找不到可執行檔,因為 chruby 修改了 PATH,使其僅包含安裝在 ~/.gem/ruby/3.3.1 下的可執行檔。

同樣地,大多數版本管理器不會讀取您的 ~/.gemrc 設定。如果您使用 --install-dir 進行自訂安裝,則版本管理器不太可能知道它。這可能會導致找不到 gem 可執行檔。

RubyGems 和像這樣版本管理器之間的不相容性超出了 Ruby LSP 的範圍,應該向 RubyGems 或各自的版本管理器回報。

在容器上開發

請參閱文件

問題診斷

許多啟動問題都與您的開發環境配置方式有關。如果您可以重現您遇到的問題,請提供關於這些步驟的資訊,這是確保我們能夠及時修復問題的最佳方式。請在您的錯誤報告中包含您為診斷問題所採取的步驟。

檢查伺服器是否正在執行

請檢查狀態中心。伺服器狀態是否顯示正在執行?如果正在執行,但您缺少某些功能,請檢查我們的功能文件,以確保我們已經增加了對它的支援。

如果該功能被列為完全支援,但對您而言無法運作,請回報問題,以便我們提供協助。

檢查 VS Code 輸出索引標籤

許多啟動步驟都會記錄在 VS Code 輸出索引標籤的 Ruby LSP 通道中。檢查日誌以查看是否有任何條目暗示問題可能所在。擴充功能是否選擇了您偏好的 Shell?

它是否選擇了您偏好的版本管理器?您可以使用 "rubyLsp.rubyVersionManager" 設定來定義要使用的版本管理器。

啟用記錄

您可以啟用記錄到 VS Code 輸出索引標籤,如 CONTRIBUTING 文件中所述

環境啟動失敗

我們在此文件中列出了與版本管理器相關的資訊和提示。

我偏好的版本管理器不受支援

我們預設支援最常見的版本管理器,但可能無法涵蓋所有可用的工具。對於這些情況,我們提供自訂啟動支援。更多資訊請參閱版本管理器的文件

嘗試手動執行 Ruby 啟動

如果擴充功能無法啟動 Ruby 環境,請嘗試在您的 Shell 中手動執行相同的命令,以查看問題是否完全與擴充功能有關。用於啟動的確切命令會列印到輸出索引標籤。

嘗試手動啟動伺服器

如果 Ruby 環境似乎已正確啟動,但伺服器無法啟動,請嘗試從終端機手動啟動,使用

# Do not use bundle exec
ruby-lsp

手動啟動伺服器是否提供任何額外資訊?還是只有透過擴充功能啟動時才會失敗?

索引

當 Ruby LSP 啟動時,它會嘗試索引您的程式碼以及您的依賴項,如設定程式碼索引中所述。

在極少數情況下,Ruby LSP 會遇到錯誤,導致索引無法完成,這將導致編輯器中的資訊不完整。

首先,請確保您使用的是最新版本的 ruby-lsp gem,因為問題可能已經被修復。

若要診斷導致問題的特定檔案,請執行 ruby-lsp-check。請記錄問題,以便我們可以解決它。如果程式碼不是開放原始碼,請提供最小的重現步驟。

同時,您可以設定 Ruby LSP 以忽略特定 gem 或檔案的索引

疑難排解後

如果在疑難排解後,Ruby LSP 仍然無法正確初始化,請在此回報問題,以便我們可以協助修復問題。請記得包含在嘗試診斷問題時所採取的步驟。


目錄