LSP(语言服务器协议)

内置语言服务器在 RuboCop 1.53 中引入。这个实验性功能已经考虑了一段时间。

语言服务器协议 是为各种编程语言提供跨编辑器支持的现代标准。

此功能通过 LSP 实现极快的交互。

编辑器和 IDE 使用语言服务器实时执行违规检测和自动更正。 服务器模式 主要用于加快终端中的 RuboCop 运行。因此,如果您希望在编辑器或 IDE 中获得 RuboCop 的实时反馈,选择使用此语言服务器而不是服务器模式,不仅可以提供快速高效的解决方案,还可以提供简便的集成设置。

LSP 客户端示例

以下是 LSP 客户端配置示例。

VS Code

vscode-rubocop 将 RuboCop 集成到 VS Code 中。

您可以从 Visual Studio Marketplace 安装此 VS Code 扩展。

对于基于 VS Code 的 IDE,如 VSCodium 或 Eclipse Theia,可以从 Open VSX Registry 安装扩展。

Emacs(Eglot)

Eglot 是 Emacs 上语言服务器协议服务器的客户端。

将以下内容添加到您的 Emacs 配置文件(例如 ~/.emacs.d/init.el

(require 'eglot)

(add-to-list 'eglot-server-programs '(ruby-mode . ("bundle" "exec" "rubocop" "--lsp")))
(add-hook 'ruby-mode-hook 'eglot-ensure)

以下是在保存时自动更正的额外设置示例

(add-hook 'ruby-mode-hook (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil 'local)))

如果您遇到问题,请先使用“M-x eglot-reconnect”重新连接到语言服务器。

有关更多信息,请参阅 Eglot 的官方文档。

Emacs(LSP 模式)

LSP 模式 是 Emacs 的语言服务器协议客户端/库。

您可以从 MELPA 获取新的 lsp-mode 包。

有关更多信息,请参阅 LSP 模式官方文档: https://emacs-lsp.github.io/lsp-mode/page/lsp-rubocop/

Vim 和 Neovim(coc.nvim)

coc.nvim 是 Vim 和 Neovim 的扩展主机,由 Node.js 提供支持。它允许加载类似于 VSCode 的扩展,并为语言服务器提供托管。

将以下内容添加到您的 coc.nvim 配置文件。例如,在 Vim 中,它将是 ~/.vim/coc-settings.json,在 Neovim 中,它将是 ~/.config/nvim/coc-settings.json

{
  "languageserver": {
    "rubocop": {
      "command": "bundle",
      "args" : ["exec", "rubocop", "--lsp"],
      "filetypes": ["ruby"],
      "rootPatterns": [".git", "Gemfile"],
      "requireRootPattern": true
    }
  }
}

以下是在保存时自动更正的额外设置示例

{
  "coc.preferences.formatOnSave": true
}

有关更多信息,请参阅 coc.nvim 的官方文档。

Neovim (nvim-lspconfig)

nvim-lspconfig 为 Neovim 的 LSP 提供快速入门配置。

将以下内容添加到您的 nvim-lspconfig 配置文件(例如 ~/.config/nvim/init.lua

vim.opt.signcolumn = "yes"
vim.api.nvim_create_autocmd("FileType", {
  pattern = "ruby",
  callback = function()
    vim.lsp.start {
      name = "rubocop",
      cmd = { "bundle", "exec", "rubocop", "--lsp" },
    }
  end,
})

以下是在保存时自动更正的额外设置示例

vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = "*.rb",
  callback = function()
    vim.lsp.buf.format()
  end,
})

有关更多信息,请参阅 nvim-lspconfig 的官方文档。

Helix

Helix 是一款后现代模态文本编辑器,内置语言服务器支持。

将以下内容添加到您的 Helix 语言配置文件(例如 ~/.config/helix/languages.toml

Helix 23.10 或更高版本

[language-server.rubocop]
command = "bundle"
args = ["exec", "rubocop", "--lsp"]

[[language]]
name = "ruby"
auto-format = true
language-servers = [
  { name = "rubocop" }
]

Helix 23.10 之前版本

[[language]]
name = "ruby"
language-server = { command = "bundle", args = ["exec", "rubocop", "--lsp"] }
auto-format = true

有关更多信息,请参阅 Helix 的官方文档:https://docs.helix-editor.com/languages.html

Sublime Text

对于 Sublime Text,LSP 支持可通过 Sublime-LSP 插件获得。将以下内容添加到其设置(可通过 Preferences → Package Settings → LSP → Settings 访问)以启用 RuboCop

{
    "clients": {
        "rubocop": {
            "enabled": true,
            "command": ["bundle", "exec", "rubocop", "--lsp"],
            "selector": "source.ruby | text.html.ruby | text.html.rails",
        },
    },
}

自动更正

语言服务器支持 textDocument/formatting 方法,并且可以自动更正。默认情况下,自动更正是安全的(rubocop -a)。

LSP 客户端可以通过在 initialize 请求中传递以下 safeAutocorrect 参数来切换到不安全的自动更正(rubocop -A)。

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "initialize",
  "params": {
    "initializationOptions": {
      "safeAutocorrect": false
    }
  }
}

有关设置参数的详细说明,请参阅您的 LSP 客户端的配置方法。

safeAutocorrect 参数是在 RuboCop 1.54 中引入的。

作为在 workspace/executeCommand 参数中执行命令,它提供了 rubocop.formatAutocorrects 用于安全自动更正(rubocop -a)和 rubocop.formatAutocorrectsAll 用于不安全的自动更正(rubocop -A)。这些参数优先于在 initialize 参数中设置的 initializationOptions:safeAutocorrect 值。

rubocop.formatAutocorrectsAll 执行命令是在 RuboCop 1.56 中引入的。

Lint 模式

如果您只想将该功能作为像 ruby -w 这样的 linter 启用,则 LSP 客户端可以通过在 initialize 请求中传递以下 lintMode 参数来运行 lint cop。

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "initialize",
  "params": {
    "initializationOptions": {
      "lintMode": true
    }
  }
}

此外,在保存时在 LSP 客户端中启用自动更正等同于 rubocop -l 选项的效果。

有关设置参数的详细说明,请参阅您的 LSP 客户端的配置方法。

lintMode 参数是在 RuboCop 1.55 中引入的。

布局模式

如果您只想将 LSP 客户端作为格式化程序启用此功能,则可以通过在 initialize 请求中传递以下 layoutMode 参数来运行布局检查器。

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "initialize",
  "params": {
    "initializationOptions": {
      "layoutMode": true
    }
  }
}

此外,在保存时在 LSP 客户端中启用自动更正等同于 rubocop -x 选项的效果。

有关设置参数的详细说明,请参阅您的 LSP 客户端的配置方法。

layoutMode 参数是在 RuboCop 1.55 中引入的。

启用 YJIT

YJIT 是一个 Ruby JIT 编译器,从 Ruby 3.1 开始支持。在 LSP 客户端中,您可以通过使用 env 命令启动 rubocop --lsp 并在环境变量中设置 RUBY_YJIT_ENABLE=1 来启用 YJIT。

env RUBY_YJIT_ENABLE=1 bundle exec rubocop --lsp

以下是 Emacs 的 Eglot 的示例。

(add-to-list 'eglot-server-programs '(ruby-mode . ("env" "RUBY_YJIT_ENABLE=1" "bundle" "exec" "rubocop" "--lsp")))

LSP 客户端的控制台将显示 +YJIT

RuboCop 1.63.4 language server +YJIT initialized, PID 13501

有关更多详细信息,请参阅相应的 LSP 配置文档。在某些情况下,例如使用 vscode-rubocop,它可能作为内置选项提供:https://github.com/rubocop/vscode-rubocop#rubocopyjitenabled

作为语言服务器运行

从 LSP 客户端运行 rubocop --lsp 命令。

语言服务器启动后,该命令将显示语言服务器的 PID。

$ ps aux | grep 'rubocop --lsp'
user             17414   0.0  0.2  5557716 144376   ??  Ss    4:48PM   0:02.13 rubocop --lsp /Users/user/src/github.com/rubocop/rubocop
rubocop --lsp 用于启动 LSP 客户端,因此用户无需手动执行它。

语言服务器开发

RuboCop 为原始语言服务器或类似于 LSP 的工具的开发人员提供 API,使用 RuboCop 作为后端,而不是 RuboCop 的内置 LSP。

  • RuboCop::LSP.enable 启用 LSP 模式,为 LSP 特定功能(如自动更正和简短违规消息)进行自定义。

  • RuboCop::LSP.disable 禁用 LSP 模式,这对于测试特别有用。并且可以指定用户有意进行的自动更正。例如,workspace/executeCommandtextDocument/codeAction LSP 方法。

在实现自定义检查器时,可以使用 RuboCop::LSP.enabled? 来实现考虑这些状态的行为。