疑難排解
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 個執行階段相依性為 rbs
、prism
和 sorbet-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 仍然無法正確初始化,請在此回報問題,以便我們可以協助修復問題。請記得包含在嘗試診斷問題時所採取的步驟。