From 75775292b3d5bb77794dce2a3c57976265282865 Mon Sep 17 00:00:00 2001 From: Vitaly Slobodin Date: Wed, 17 Jul 2024 23:29:42 +0200 Subject: [PATCH] ruby: Add support for "rubocop" language server (#14661) Hi, this pull request adds support for `rubocop` language server. I noticed that `ruby-lsp` LS is becoming more popular but it still lacks diagnostics support in Zed. To cover that missing feature, it could be good to use `rubocop` LS to show diagnostics alongside with the running Ruby LSP. Release Notes: - N/A --------- Co-authored-by: Marshall Bowers --- assets/settings/default.json | 2 +- docs/src/languages/ruby.md | 39 ++++++++++++++++++- extensions/ruby/extension.toml | 4 ++ extensions/ruby/src/language_servers.rs | 2 + .../ruby/src/language_servers/rubocop.rs | 19 +++++++++ extensions/ruby/src/ruby.rs | 13 ++++++- 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 extensions/ruby/src/language_servers/rubocop.rs diff --git a/assets/settings/default.json b/assets/settings/default.json index 693041cce5..042538e3c0 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -798,7 +798,7 @@ } }, "Ruby": { - "language_servers": ["solargraph", "!ruby-lsp", "..."] + "language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."] }, "SCSS": { "prettier": { diff --git a/docs/src/languages/ruby.md b/docs/src/languages/ruby.md index ab8f549ba4..1e1f006305 100644 --- a/docs/src/languages/ruby.md +++ b/docs/src/languages/ruby.md @@ -16,7 +16,20 @@ To switch to `ruby-lsp`, add the following to your `settings.json`: { "languages": { "Ruby": { - "language_servers": ["ruby-lsp", "!solargraph", "..."] + "language_servers": ["ruby-lsp", "!solargraph", "!rubocop", "..."] + } + } +} +``` + +The Ruby extension also provides support for `rubocop` language server for offense detection and autocorrection. To enable it, add the following to your +`settings.json`: + +```json +{ + "languages": { + "Ruby": { + "language_servers": ["rubocop", "ruby-lsp", "!solargraph", "..."] } } } @@ -83,6 +96,30 @@ Ruby LSP uses pull-based diagnostics which Zed doesn't support yet. We can tell } ``` +## Setting up `rubocop` LSP + +Zed currently doesn't install `rubocop` automatically. To use `rubocop`, you need to install the gem. Zed just looks for an executable called `rubocop` on your `PATH`. + +You can install the gem manually with the following command: + +```shell +gem install rubocop +``` + +Rubocop has unsafe autocorrection disabled by default. We can tell Zed to enable it by adding the following to your `settings.json`: + +```json +{ + "lsp": { + "rubocop": { + "initialization_options": { + "safeAutocorrect": false + } + } + } +} +``` + ## Using the Tailwind CSS Language Server with Ruby It's possible to use the [Tailwind CSS Language Server](https://github.com/tailwindlabs/tailwindcss-intellisense/tree/HEAD/packages/tailwindcss-language-server#readme) in Ruby and ERB files. diff --git a/extensions/ruby/extension.toml b/extensions/ruby/extension.toml index 9465510ce0..fe7954ac43 100644 --- a/extensions/ruby/extension.toml +++ b/extensions/ruby/extension.toml @@ -14,6 +14,10 @@ language = "Ruby" name = "Ruby LSP" language = "Ruby" +[language_servers.rubocop] +name = "Rubocop" +language = "Ruby" + [grammars.ruby] repository = "https://github.com/tree-sitter/tree-sitter-ruby" commit = "dc2d7d6b50f9975bc3c35bbec0ba11b2617b736b" diff --git a/extensions/ruby/src/language_servers.rs b/extensions/ruby/src/language_servers.rs index f2afc44e88..3ad3de55ea 100644 --- a/extensions/ruby/src/language_servers.rs +++ b/extensions/ruby/src/language_servers.rs @@ -1,5 +1,7 @@ +mod rubocop; mod ruby_lsp; mod solargraph; +pub use rubocop::*; pub use ruby_lsp::*; pub use solargraph::*; diff --git a/extensions/ruby/src/language_servers/rubocop.rs b/extensions/ruby/src/language_servers/rubocop.rs new file mode 100644 index 0000000000..6ce2621665 --- /dev/null +++ b/extensions/ruby/src/language_servers/rubocop.rs @@ -0,0 +1,19 @@ +use zed_extension_api::{self as zed, Result}; + +pub struct Rubocop {} + +impl Rubocop { + pub const LANGUAGE_SERVER_ID: &'static str = "rubocop"; + + pub fn new() -> Self { + Self {} + } + + pub fn server_script_path(&mut self, worktree: &zed::Worktree) -> Result { + let path = worktree.which("rubocop").ok_or_else(|| { + "rubocop must be installed manually. Install it with `gem install rubocop` or specify the 'binary' path to it via local settings.".to_string() + })?; + + Ok(path) + } +} diff --git a/extensions/ruby/src/ruby.rs b/extensions/ruby/src/ruby.rs index b42ea0450b..af49202fdf 100644 --- a/extensions/ruby/src/ruby.rs +++ b/extensions/ruby/src/ruby.rs @@ -5,11 +5,12 @@ use zed::settings::LspSettings; use zed::{serde_json, CodeLabel, LanguageServerId}; use zed_extension_api::{self as zed, Result}; -use crate::language_servers::{RubyLsp, Solargraph}; +use crate::language_servers::{Rubocop, RubyLsp, Solargraph}; struct RubyExtension { solargraph: Option, ruby_lsp: Option, + rubocop: Option, } impl zed::Extension for RubyExtension { @@ -17,6 +18,7 @@ impl zed::Extension for RubyExtension { Self { solargraph: None, ruby_lsp: None, + rubocop: None, } } @@ -44,6 +46,15 @@ impl zed::Extension for RubyExtension { env: worktree.shell_env(), }) } + Rubocop::LANGUAGE_SERVER_ID => { + let rubocop = self.rubocop.get_or_insert_with(|| Rubocop::new()); + + Ok(zed::Command { + command: rubocop.server_script_path(worktree)?, + args: vec!["--lsp".into()], + env: worktree.shell_env(), + }) + } language_server_id => Err(format!("unknown language server: {language_server_id}")), } }