ruby: Move Ruby extension to zed-extensions/ruby repo (#19098)

Peter Tripp created

Change summary

Cargo.lock                                         |   7 
Cargo.toml                                         |   1 
docs/src/languages/ruby.md                         |   4 
extensions/ruby/Cargo.toml                         |  16 -
extensions/ruby/LICENSE-APACHE                     |   1 
extensions/ruby/extension.toml                     |  31 --
extensions/ruby/languages/erb/config.toml          |   9 
extensions/ruby/languages/erb/highlights.scm       |  12 
extensions/ruby/languages/erb/injections.scm       |   7 
extensions/ruby/languages/rbs/config.toml          |  10 
extensions/ruby/languages/rbs/highlights.scm       | 144 -----------
extensions/ruby/languages/rbs/indents.scm          |  14 -
extensions/ruby/languages/rbs/injections.scm       |   2 
extensions/ruby/languages/ruby/brackets.scm        |  14 -
extensions/ruby/languages/ruby/config.toml         |  51 ----
extensions/ruby/languages/ruby/embedding.scm       |  22 -
extensions/ruby/languages/ruby/highlights.scm      | 202 ----------------
extensions/ruby/languages/ruby/indents.scm         |  18 -
extensions/ruby/languages/ruby/injections.scm      |   8 
extensions/ruby/languages/ruby/outline.scm         |  20 -
extensions/ruby/languages/ruby/overrides.scm       |   3 
extensions/ruby/languages/ruby/runnables.scm       |  58 ----
extensions/ruby/languages/ruby/tasks.json          |   7 
extensions/ruby/src/language_servers.rs            |   7 
extensions/ruby/src/language_servers/rubocop.rs    |  59 ----
extensions/ruby/src/language_servers/ruby_lsp.rs   | 128 ----------
extensions/ruby/src/language_servers/solargraph.rs | 156 ------------
extensions/ruby/src/ruby.rs                        |  88 ------
28 files changed, 2 insertions(+), 1,097 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -14828,13 +14828,6 @@ dependencies = [
  "zed_extension_api 0.1.0",
 ]
 
-[[package]]
-name = "zed_ruby"
-version = "0.2.0"
-dependencies = [
- "zed_extension_api 0.1.0",
-]
-
 [[package]]
 name = "zed_ruff"
 version = "0.1.0"

Cargo.toml 🔗

@@ -156,7 +156,6 @@ members = [
     "extensions/proto",
     "extensions/purescript",
     "extensions/ruff",
-    "extensions/ruby",
     "extensions/slash-commands-example",
     "extensions/snippets",
     "extensions/svelte",

docs/src/languages/ruby.md 🔗

@@ -1,6 +1,6 @@
 # Ruby
 
-Ruby support is available through the [Ruby extension](https://github.com/zed-industries/zed/tree/main/extensions/ruby).
+Ruby support is available through the [Ruby extension](https://github.com/zed-extensions/ruby).
 
 - Tree-sitters:
   - [tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby)
@@ -25,7 +25,7 @@ In addition to these two language servers, Zed also supports [rubocop](https://g
 
 ## Configuring a language server
 
-The [Ruby extension](https://github.com/zed-industries/zed/tree/main/extensions/ruby) offers both `solargraph` and `ruby-lsp` language server support.
+The [Ruby extension](https://github.com/zed-extensions/ruby) offers both `solargraph` and `ruby-lsp` language server support.
 
 ### Using `solargraph`
 

extensions/ruby/Cargo.toml 🔗

@@ -1,16 +0,0 @@
-[package]
-name = "zed_ruby"
-version = "0.2.0"
-edition = "2021"
-publish = false
-license = "Apache-2.0"
-
-[lints]
-workspace = true
-
-[lib]
-path = "src/ruby.rs"
-crate-type = ["cdylib"]
-
-[dependencies]
-zed_extension_api = "0.1.0"

extensions/ruby/extension.toml 🔗

@@ -1,31 +0,0 @@
-id = "ruby"
-name = "Ruby"
-description = "Ruby support."
-version = "0.2.0"
-schema_version = 1
-authors = ["Vitaly Slobodin <vitaliy.slobodin@gmail.com>"]
-repository = "https://github.com/zed-industries/zed"
-
-[language_servers.solargraph]
-name = "Solargraph"
-languages = ["Ruby"]
-
-[language_servers.ruby-lsp]
-name = "Ruby LSP"
-languages = ["Ruby", "ERB"]
-
-[language_servers.rubocop]
-name = "Rubocop"
-languages = ["Ruby"]
-
-[grammars.ruby]
-repository = "https://github.com/tree-sitter/tree-sitter-ruby"
-commit = "7dbc1e2d0e2d752577655881f73b4573f3fe85d4"
-
-[grammars.embedded_template]
-repository = "https://github.com/tree-sitter/tree-sitter-embedded-template"
-commit = "91fc5ae1140d5c9d922312431f7d251a48d7b8ce"
-
-[grammars.rbs]
-repository = "https://github.com/joker1007/tree-sitter-rbs"
-commit = "8d8e65ac3f77fbc9e15b1cdb9f980a3e0ac3ab99"

extensions/ruby/languages/erb/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "ERB"
-grammar = "embedded_template"
-path_suffixes = ["erb"]
-autoclose_before = ">})"
-brackets = [
-    { start = "<", end = ">", close = true, newline = true },
-]
-block_comment = ["<%#", "%>"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]

extensions/ruby/languages/rbs/config.toml 🔗

@@ -1,10 +0,0 @@
-name = "RBS"
-grammar = "rbs"
-path_suffixes = ["rbs"]
-autoclose_before = "]})"
-brackets = [
-    { start = "(", end = ")", close = true, newline = false },
-    { start = "{", end = "}", close = true, newline = false },
-    { start = "[", end = "]", close = true, newline = false },
-]
-line_comments = ["#"]

extensions/ruby/languages/rbs/highlights.scm 🔗

@@ -1,144 +0,0 @@
-; Taken from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/rbs/highlights.scm
-; Use directive
-(use_clause
-  [
-    (type_name)
-    (simple_type_name)
-  ] @type)
-
-; Builtin constants and Keywords
-[
-  "true"
-  "false"
-] @boolean
-
-"nil" @constant.builtin
-
-[
-  "use"
-  "as"
-  "module"
-  "def"
-  "attr_reader"
-  "attr_writer"
-  "attr_accessor"
-  "end"
-  "alias"
-] @keyword
-
-[
-  "interface"
-  "type"
-  "class"
-] @keyword.type
-
-(class_decl
-  "end" @keyword.type)
-
-(interface_decl
-  "end" @keyword.type)
-
-"def" @keyword.function
-
-; Members of declaration
-[
-  "include"
-  "extend"
-  "prepend"
-] @function.method
-
-(visibility) @keyword.modifier
-
-(comment) @comment
-
-(method_member
-  (method_name
-    [
-      (identifier)
-      (constant)
-      (operator)
-      (setter)
-    ] @function.method))
-
-[
-  (ivar_name)
-  (cvar_name)
-] @variable.member
-
-(alias_member
-  (method_name) @function)
-
-(class_name
-  (constant) @type)
-
-(module_name
-  (constant) @type)
-
-(interface_name
-  (interface) @type)
-
-(alias_name
-  (identifier) @type)
-
-(type_variable) @constant
-
-(namespace
-  (constant) @module)
-
-(builtin_type) @type.builtin
-
-(const_name
-  (constant) @constant)
-
-(global_name) @variable
-
-; Standard Arguments
-(parameter
-  (var_name) @variable.parameter)
-
-; Keyword Arguments
-(keyword) @variable.parameter
-
-; Self
-(self) @variable.builtin
-
-; Literal
-(type
-  (symbol_literal) @string.special.symbol)
-
-(type
-  (string_literal
-    (escape_sequence) @string.escape))
-
-(type
-  (string_literal) @string)
-
-(type
-  (integer_literal) @number)
-
-; Operators
-[
-  "="
-  "->"
-  "<"
-  "**"
-  "*"
-  "&"
-  "|"
-  "^"
-] @operator
-
-; Punctuation
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-] @punctuation.bracket
-
-[
-  ","
-  "."
-] @punctuation.delimiter

extensions/ruby/languages/rbs/indents.scm 🔗

@@ -1,14 +0,0 @@
-[
-  (class_decl)
-  (module_decl)
-  (interface_decl)
-  (parameters)
-  (tuple_type)
-  (record_type)
-] @indent.begin
-
-(_ "[" "]" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent
-
-(comment) @indent.ignore

extensions/ruby/languages/ruby/brackets.scm 🔗

@@ -1,14 +0,0 @@
-("[" @open "]" @close)
-("{" @open "}" @close)
-("\"" @open "\"" @close)
-("do" @open "end" @close)
-
-(block_parameters "|" @open "|" @close)
-(interpolation "#{" @open "}" @close)
-
-(if "if" @open "end" @close)
-(unless "unless" @open "end" @close)
-(begin "begin" @open "end" @close)
-(module "module" @open "end" @close)
-(_ . "def" @open "end" @close)
-(_ . "class" @open "end" @close)

extensions/ruby/languages/ruby/config.toml 🔗

@@ -1,51 +0,0 @@
-name = "Ruby"
-grammar = "ruby"
-path_suffixes = [
-    "rb",
-    "Gemfile",
-    "Guardfile",
-    "rake",
-    "Rakefile",
-    "ru",
-    "thor",
-    "cap",
-    "capfile",
-    "Capfile",
-    "jbuilder",
-    "rabl",
-    "rxml",
-    "builder",
-    "gemspec",
-    "rdoc",
-    "thor",
-    "pryrc",
-    "simplecov",
-    "Steepfile",
-    "Podfile",
-    "Brewfile",
-    "Vagrantfile",
-    "Puppetfile",
-]
-first_line_pattern = '^#!.*\bruby\b'
-line_comments = ["# "]
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = [
-        "comment",
-        "string",
-    ] },
-    { start = "'", end = "'", close = true, newline = false, not_in = [
-        "comment",
-        "string",
-    ] },
-]
-collapsed_placeholder = "# ..."
-tab_size = 2
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

extensions/ruby/languages/ruby/embedding.scm 🔗

@@ -1,22 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (module
-            "module" @name
-            name: (_) @name)
-        (method
-            "def" @name
-            name: (_) @name
-            body: (body_statement) @collapse)
-        (class
-            "class" @name
-            name: (_) @name)
-        (singleton_method
-            "def" @name
-            object: (_) @name
-            "." @name
-            name: (_) @name
-            body: (body_statement) @collapse)
-        ] @item
-    )

extensions/ruby/languages/ruby/highlights.scm 🔗

@@ -1,202 +0,0 @@
-; Keywords
-
-[
-  "alias"
-  "and"
-  "begin"
-  "break"
-  "case"
-  "class"
-  "def"
-  "do"
-  "else"
-  "elsif"
-  "end"
-  "ensure"
-  "for"
-  "if"
-  "in"
-  "module"
-  "next"
-  "or"
-  "rescue"
-  "retry"
-  "return"
-  "then"
-  "unless"
-  "until"
-  "when"
-  "while"
-  "yield"
-] @keyword
-
-((identifier) @keyword
- (#match? @keyword "^(private|protected|public)$"))
-
-; Function calls
-
-((identifier) @function.method.builtin
- (#eq? @function.method.builtin "require"))
-
-"defined?" @function.method.builtin
-
-(call
-  method: [(identifier) (constant)] @function.method)
-
-; Function definitions
-
-(alias (identifier) @function.method)
-(setter (identifier) @function.method)
-(method name: [(identifier) (constant)] @function.method)
-(singleton_method name: [(identifier) (constant)] @function.method)
-(method_parameters [
-  (identifier) @variable.parameter
-  (optional_parameter name: (identifier) @variable.parameter)
-  (keyword_parameter [name: (identifier) (":")] @variable.parameter)
-  ])
-
-(block_parameters (identifier) @variable.parameter)
-
-; Identifiers
-
-((identifier) @constant.builtin
- (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
-
-(file) @constant.builtin
-(line) @constant.builtin
-(encoding) @constant.builtin
-
-(hash_splat_nil
-  "**" @operator
-) @constant.builtin
-
-(global_variable) @constant
-
-(constant) @type
-
-((constant) @constant
- (#match? @constant "^[A-Z\\d_]+$"))
-
-(superclass
-  (constant) @type.super)
-
-(superclass
-  (scope_resolution
-    (constant) @type.super))
-
-(superclass
-  (scope_resolution
-    (scope_resolution
-      (constant) @type.super)))
-
-(self) @variable.special
-(super) @variable.special
-
-[
-  (class_variable)
-  (instance_variable)
-] @variable.member
-
-
-; Literals
-
-[
-  (string)
-  (bare_string)
-  (subshell)
-  (heredoc_body)
-  (heredoc_beginning)
-] @string
-
-[
-  (simple_symbol)
-  (delimited_symbol)
-  (hash_key_symbol)
-  (bare_symbol)
-] @string.special.symbol
-
-(regex) @string.regex
-(escape_sequence) @string.escape
-
-[
-  (integer)
-  (float)
-] @number
-
-[
-  (nil)
-  (true)
-  (false)
-] @constant.builtin
-
-(comment) @comment
-
-; Operators
-
-[
-  "!"
-  "~"
-  "+"
-  "-"
-  "**"
-  "*"
-  "/"
-  "%"
-  "<<"
-  ">>"
-  "&"
-  "|"
-  "^"
-  ">"
-  "<"
-  "<="
-  ">="
-  "=="
-  "!="
-  "=~"
-  "!~"
-  "<=>"
-  "||"
-  "&&"
-  ".."
-  "..."
-  "="
-  "**="
-  "*="
-  "/="
-  "%="
-  "+="
-  "-="
-  "<<="
-  ">>="
-  "&&="
-  "&="
-  "||="
-  "|="
-  "^="
-  "=>"
-  "->"
-  (operator)
-] @operator
-
-[
-  ","
-  ";"
-  "."
-  "::"
-] @punctuation.delimiter
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-  "%w("
-  "%i("
-] @punctuation.bracket
-
-(interpolation
-  "#{" @punctuation.special
-  "}" @punctuation.special) @embedded

extensions/ruby/languages/ruby/indents.scm 🔗

@@ -1,18 +0,0 @@
-(method "end" @end) @indent
-(class "end" @end) @indent
-(module "end" @end) @indent
-(begin "end" @end) @indent
-(singleton_method "end" @end) @indent
-(do_block "end" @end) @indent
-
-(then) @indent
-(call) @indent
-
-(ensure) @outdent
-(rescue) @outdent
-(else) @outdent
-
-
-(_ "[" "]" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

extensions/ruby/languages/ruby/outline.scm 🔗

@@ -1,20 +0,0 @@
-(class
-    "class" @context
-    name: (_) @name) @item
-
-((identifier) @context
-  (#match? @context "^(private|protected|public)$")) @item
-
-(method
-    "def" @context
-    name: (_) @name) @item
-
-(singleton_method
-    "def" @context
-    object: (_) @context
-    "." @context
-    name: (_) @name) @item
-
-(module
-    "module" @context
-    name: (_) @name) @item

extensions/ruby/languages/ruby/runnables.scm 🔗

@@ -1,58 +0,0 @@
-; Adapted from the following sources:
-; Minitest: https://github.com/zidhuss/neotest-minitest/blob/main/lua/neotest-minitest/init.lua
-; RSpec: https://github.com/olimorris/neotest-rspec/blob/main/lua/neotest-rspec/init.lua
-
-; Tests that inherit from a specific class
-(
-    (class
-        name: [
-          (constant) @run
-          (scope_resolution scope: (constant) name: (constant) @run)
-        ]
-        (superclass (scope_resolution) @superclass (#match? @superclass "(::IntegrationTest|::TestCase|::SystemTestCase|Minitest::Test|TLDR)$"))
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)
-
-(
-    (call
-        method: (identifier) @run (#eq? @run "test")
-        arguments: (argument_list (string (string_content) @_name))
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)
-
-; Methods that begin with test_
-(
-    (method
-        name: (identifier) @run (#match? @run "^test_")
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)
-
-; System tests that inherit from ApplicationSystemTestCase
-(
-    (class
-        name: (constant) @run (superclass) @superclass (#match? @superclass "(ApplicationSystemTestCase)$")
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)
-
-; Examples
-(
-    (call
-       method: (identifier) @run (#any-of? @run "describe" "context" "it" "its" "specify")
-       arguments: (argument_list . (_) @_name)
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)
-
-; Examples (one-liner syntax)
-(
-    (call
-        method: (identifier) @run (#any-of? @run "it" "its" "specify")
-        block: (_) @_name
-        !arguments
-    ) @_ruby-test
-    (#set! tag ruby-test)
-)

extensions/ruby/languages/ruby/tasks.json 🔗

@@ -1,7 +0,0 @@
-[
-  {
-    "label": "test $ZED_RELATIVE_FILE:$ZED_ROW",
-    "command": "echo 'To run tests, configure tasks in your \".zed/tasks.json\" file as described in the Ruby extension documentation.'",
-    "tags": ["ruby-test"]
-  }
-]

extensions/ruby/src/language_servers/rubocop.rs 🔗

@@ -1,59 +0,0 @@
-use zed_extension_api::{self as zed, settings::LspSettings, LanguageServerId, Result};
-
-pub struct RubocopBinary {
-    pub path: String,
-    pub args: Option<Vec<String>>,
-}
-
-pub struct Rubocop {}
-
-impl Rubocop {
-    pub const LANGUAGE_SERVER_ID: &'static str = "rubocop";
-
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    pub fn language_server_command(
-        &mut self,
-        language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        let binary = self.language_server_binary(language_server_id, worktree)?;
-
-        Ok(zed::Command {
-            command: binary.path,
-            args: binary.args.unwrap_or_else(|| vec!["--lsp".to_string()]),
-            env: worktree.shell_env(),
-        })
-    }
-
-    fn language_server_binary(
-        &self,
-        _language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<RubocopBinary> {
-        let binary_settings = LspSettings::for_worktree("rubocop", worktree)
-            .ok()
-            .and_then(|lsp_settings| lsp_settings.binary);
-        let binary_args = binary_settings
-            .as_ref()
-            .and_then(|binary_settings| binary_settings.arguments.clone());
-
-        if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
-            return Ok(RubocopBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        if let Some(path) = worktree.which("rubocop") {
-            return Ok(RubocopBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        Err("rubocop must be installed manually. Install it with `gem install rubocop` or specify the 'binary' path to it via local settings.".to_string())
-    }
-}

extensions/ruby/src/language_servers/ruby_lsp.rs 🔗

@@ -1,128 +0,0 @@
-use zed_extension_api::{
-    self as zed,
-    lsp::{Completion, CompletionKind, Symbol, SymbolKind},
-    settings::LspSettings,
-    CodeLabel, CodeLabelSpan, LanguageServerId, Result,
-};
-
-pub struct RubyLspBinary {
-    pub path: String,
-    pub args: Option<Vec<String>>,
-}
-
-pub struct RubyLsp {}
-
-impl RubyLsp {
-    pub const LANGUAGE_SERVER_ID: &'static str = "ruby-lsp";
-
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    pub fn language_server_command(
-        &mut self,
-        language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        let binary = self.language_server_binary(language_server_id, worktree)?;
-
-        Ok(zed::Command {
-            command: binary.path,
-            args: binary.args.unwrap_or_default(),
-            env: worktree.shell_env(),
-        })
-    }
-
-    fn language_server_binary(
-        &self,
-        _language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<RubyLspBinary> {
-        let binary_settings = LspSettings::for_worktree("ruby-lsp", worktree)
-            .ok()
-            .and_then(|lsp_settings| lsp_settings.binary);
-        let binary_args = binary_settings
-            .as_ref()
-            .and_then(|binary_settings| binary_settings.arguments.clone());
-
-        if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
-            return Ok(RubyLspBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        if let Some(path) = worktree.which("ruby-lsp") {
-            return Ok(RubyLspBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        Err(
-            "ruby-lsp must be installed manually. Install it with `gem install ruby-lsp`."
-                .to_string(),
-        )
-    }
-
-    pub fn label_for_completion(&self, completion: Completion) -> Option<CodeLabel> {
-        let highlight_name = match completion.kind? {
-            CompletionKind::Class | CompletionKind::Module => "type",
-            CompletionKind::Constant => "constant",
-            CompletionKind::Method => "function.method",
-            CompletionKind::Reference => "function.method",
-            CompletionKind::Keyword => "keyword",
-            _ => return None,
-        };
-
-        let len = completion.label.len();
-        let name_span = CodeLabelSpan::literal(completion.label, Some(highlight_name.to_string()));
-
-        Some(CodeLabel {
-            code: Default::default(),
-            spans: vec![name_span],
-            filter_range: (0..len).into(),
-        })
-    }
-
-    pub fn label_for_symbol(&self, symbol: Symbol) -> Option<CodeLabel> {
-        let name = &symbol.name;
-
-        match symbol.kind {
-            SymbolKind::Method => {
-                let code = format!("def {name}; end");
-                let filter_range = 0..name.len();
-                let display_range = 4..4 + name.len();
-
-                Some(CodeLabel {
-                    code,
-                    spans: vec![CodeLabelSpan::code_range(display_range)],
-                    filter_range: filter_range.into(),
-                })
-            }
-            SymbolKind::Class | SymbolKind::Module => {
-                let code = format!("class {name}; end");
-                let filter_range = 0..name.len();
-                let display_range = 6..6 + name.len();
-
-                Some(CodeLabel {
-                    code,
-                    spans: vec![CodeLabelSpan::code_range(display_range)],
-                    filter_range: filter_range.into(),
-                })
-            }
-            SymbolKind::Constant => {
-                let code = name.to_uppercase().to_string();
-                let filter_range = 0..name.len();
-                let display_range = 0..name.len();
-
-                Some(CodeLabel {
-                    code,
-                    spans: vec![CodeLabelSpan::code_range(display_range)],
-                    filter_range: filter_range.into(),
-                })
-            }
-            _ => None,
-        }
-    }
-}

extensions/ruby/src/language_servers/solargraph.rs 🔗

@@ -1,156 +0,0 @@
-use zed::lsp::{Completion, CompletionKind, Symbol, SymbolKind};
-use zed::{CodeLabel, CodeLabelSpan};
-use zed_extension_api::settings::LspSettings;
-use zed_extension_api::{self as zed, LanguageServerId, Result};
-
-pub struct SolargraphBinary {
-    pub path: String,
-    pub args: Option<Vec<String>>,
-}
-
-pub struct Solargraph {}
-
-impl Solargraph {
-    pub const LANGUAGE_SERVER_ID: &'static str = "solargraph";
-
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    pub fn language_server_command(
-        &mut self,
-        language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        let binary = self.language_server_binary(language_server_id, worktree)?;
-
-        Ok(zed::Command {
-            command: binary.path,
-            args: binary.args.unwrap_or_else(|| vec!["stdio".to_string()]),
-            env: worktree.shell_env(),
-        })
-    }
-
-    fn language_server_binary(
-        &self,
-        _language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<SolargraphBinary> {
-        let binary_settings = LspSettings::for_worktree("solargraph", worktree)
-            .ok()
-            .and_then(|lsp_settings| lsp_settings.binary);
-        let binary_args = binary_settings
-            .as_ref()
-            .and_then(|binary_settings| binary_settings.arguments.clone());
-
-        if let Some(path) = binary_settings.and_then(|binary_settings| binary_settings.path) {
-            return Ok(SolargraphBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        if let Some(path) = worktree.which("solargraph") {
-            return Ok(SolargraphBinary {
-                path,
-                args: binary_args,
-            });
-        }
-
-        Err("solargraph must be installed manually".to_string())
-    }
-
-    pub fn label_for_completion(&self, completion: Completion) -> Option<CodeLabel> {
-        let highlight_name = match completion.kind? {
-            CompletionKind::Class | CompletionKind::Module => "type",
-            CompletionKind::Constant => "constant",
-            CompletionKind::Method => "function.method",
-            CompletionKind::Keyword => {
-                if completion.label.starts_with(':') {
-                    "string.special.symbol"
-                } else {
-                    "keyword"
-                }
-            }
-            CompletionKind::Variable => {
-                if completion.label.starts_with('@') {
-                    "property"
-                } else {
-                    return None;
-                }
-            }
-            _ => return None,
-        };
-
-        let len = completion.label.len();
-        let name_span = CodeLabelSpan::literal(completion.label, Some(highlight_name.to_string()));
-
-        Some(CodeLabel {
-            code: Default::default(),
-            spans: if let Some(detail) = completion.detail {
-                vec![
-                    name_span,
-                    CodeLabelSpan::literal(" ", None),
-                    CodeLabelSpan::literal(detail, None),
-                ]
-            } else {
-                vec![name_span]
-            },
-            filter_range: (0..len).into(),
-        })
-    }
-
-    pub fn label_for_symbol(&self, symbol: Symbol) -> Option<CodeLabel> {
-        let name = &symbol.name;
-
-        return match symbol.kind {
-            SymbolKind::Method => {
-                let mut parts = name.split('#');
-                let container_name = parts.next()?;
-                let method_name = parts.next()?;
-
-                if parts.next().is_some() {
-                    return None;
-                }
-
-                let filter_range = 0..name.len();
-
-                let spans = vec![
-                    CodeLabelSpan::literal(container_name, Some("type".to_string())),
-                    CodeLabelSpan::literal("#", None),
-                    CodeLabelSpan::literal(method_name, Some("function.method".to_string())),
-                ];
-
-                Some(CodeLabel {
-                    code: name.to_string(),
-                    spans,
-                    filter_range: filter_range.into(),
-                })
-            }
-            SymbolKind::Class | SymbolKind::Module => {
-                let class = "class ";
-                let code = format!("{class}{name}");
-                let filter_range = 0..name.len();
-                let display_range = class.len()..class.len() + name.len();
-
-                Some(CodeLabel {
-                    code,
-                    spans: vec![CodeLabelSpan::code_range(display_range)],
-                    filter_range: filter_range.into(),
-                })
-            }
-            SymbolKind::Constant => {
-                let code = name.to_uppercase().to_string();
-                let filter_range = 0..name.len();
-                let display_range = 0..name.len();
-
-                Some(CodeLabel {
-                    code,
-                    spans: vec![CodeLabelSpan::code_range(display_range)],
-                    filter_range: filter_range.into(),
-                })
-            }
-            _ => None,
-        };
-    }
-}

extensions/ruby/src/ruby.rs 🔗

@@ -1,88 +0,0 @@
-mod language_servers;
-
-use zed::lsp::{Completion, Symbol};
-use zed::settings::LspSettings;
-use zed::{serde_json, CodeLabel, LanguageServerId};
-use zed_extension_api::{self as zed, Result};
-
-use crate::language_servers::{Rubocop, RubyLsp, Solargraph};
-
-struct RubyExtension {
-    solargraph: Option<Solargraph>,
-    ruby_lsp: Option<RubyLsp>,
-    rubocop: Option<Rubocop>,
-}
-
-impl zed::Extension for RubyExtension {
-    fn new() -> Self {
-        Self {
-            solargraph: None,
-            ruby_lsp: None,
-            rubocop: None,
-        }
-    }
-
-    fn language_server_command(
-        &mut self,
-        language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<zed::Command> {
-        match language_server_id.as_ref() {
-            Solargraph::LANGUAGE_SERVER_ID => {
-                let solargraph = self.solargraph.get_or_insert_with(Solargraph::new);
-                solargraph.language_server_command(language_server_id, worktree)
-            }
-            RubyLsp::LANGUAGE_SERVER_ID => {
-                let ruby_lsp = self.ruby_lsp.get_or_insert_with(RubyLsp::new);
-                ruby_lsp.language_server_command(language_server_id, worktree)
-            }
-            Rubocop::LANGUAGE_SERVER_ID => {
-                let rubocop = self.rubocop.get_or_insert_with(Rubocop::new);
-                rubocop.language_server_command(language_server_id, worktree)
-            }
-            language_server_id => Err(format!("unknown language server: {language_server_id}")),
-        }
-    }
-
-    fn label_for_symbol(
-        &self,
-        language_server_id: &LanguageServerId,
-        symbol: Symbol,
-    ) -> Option<CodeLabel> {
-        match language_server_id.as_ref() {
-            Solargraph::LANGUAGE_SERVER_ID => self.solargraph.as_ref()?.label_for_symbol(symbol),
-            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_symbol(symbol),
-            _ => None,
-        }
-    }
-
-    fn label_for_completion(
-        &self,
-        language_server_id: &LanguageServerId,
-        completion: Completion,
-    ) -> Option<CodeLabel> {
-        match language_server_id.as_ref() {
-            Solargraph::LANGUAGE_SERVER_ID => {
-                self.solargraph.as_ref()?.label_for_completion(completion)
-            }
-            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_completion(completion),
-            _ => None,
-        }
-    }
-
-    fn language_server_initialization_options(
-        &mut self,
-        language_server_id: &LanguageServerId,
-        worktree: &zed::Worktree,
-    ) -> Result<Option<serde_json::Value>> {
-        let initialization_options =
-            LspSettings::for_worktree(language_server_id.as_ref(), worktree)
-                .ok()
-                .and_then(|lsp_settings| lsp_settings.initialization_options.clone())
-                .unwrap_or_default();
-
-        Ok(Some(serde_json::json!(initialization_options)))
-    }
-}
-
-zed::register_extension!(RubyExtension);