ruby.rs

  1mod language_servers;
  2
  3use zed::lsp::{Completion, Symbol};
  4use zed::settings::LspSettings;
  5use zed::{serde_json, CodeLabel, LanguageServerId};
  6use zed_extension_api::{self as zed, Result};
  7
  8use crate::language_servers::{Rubocop, RubyLsp, Solargraph};
  9
 10struct RubyExtension {
 11    solargraph: Option<Solargraph>,
 12    ruby_lsp: Option<RubyLsp>,
 13    rubocop: Option<Rubocop>,
 14}
 15
 16impl zed::Extension for RubyExtension {
 17    fn new() -> Self {
 18        Self {
 19            solargraph: None,
 20            ruby_lsp: None,
 21            rubocop: None,
 22        }
 23    }
 24
 25    fn language_server_command(
 26        &mut self,
 27        language_server_id: &LanguageServerId,
 28        worktree: &zed::Worktree,
 29    ) -> Result<zed::Command> {
 30        match language_server_id.as_ref() {
 31            Solargraph::LANGUAGE_SERVER_ID => {
 32                let solargraph = self.solargraph.get_or_insert_with(|| Solargraph::new());
 33
 34                Ok(zed::Command {
 35                    command: solargraph.server_script_path(worktree)?,
 36                    args: vec!["stdio".into()],
 37                    env: worktree.shell_env(),
 38                })
 39            }
 40            RubyLsp::LANGUAGE_SERVER_ID => {
 41                let ruby_lsp = self.ruby_lsp.get_or_insert_with(|| RubyLsp::new());
 42
 43                Ok(zed::Command {
 44                    command: ruby_lsp.server_script_path(worktree)?,
 45                    args: vec![],
 46                    env: worktree.shell_env(),
 47                })
 48            }
 49            Rubocop::LANGUAGE_SERVER_ID => {
 50                let rubocop = self.rubocop.get_or_insert_with(|| Rubocop::new());
 51
 52                Ok(zed::Command {
 53                    command: rubocop.server_script_path(worktree)?,
 54                    args: vec!["--lsp".into()],
 55                    env: worktree.shell_env(),
 56                })
 57            }
 58            language_server_id => Err(format!("unknown language server: {language_server_id}")),
 59        }
 60    }
 61
 62    fn label_for_symbol(
 63        &self,
 64        language_server_id: &LanguageServerId,
 65        symbol: Symbol,
 66    ) -> Option<CodeLabel> {
 67        match language_server_id.as_ref() {
 68            Solargraph::LANGUAGE_SERVER_ID => self.solargraph.as_ref()?.label_for_symbol(symbol),
 69            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_symbol(symbol),
 70            _ => None,
 71        }
 72    }
 73
 74    fn label_for_completion(
 75        &self,
 76        language_server_id: &LanguageServerId,
 77        completion: Completion,
 78    ) -> Option<CodeLabel> {
 79        match language_server_id.as_ref() {
 80            Solargraph::LANGUAGE_SERVER_ID => {
 81                self.solargraph.as_ref()?.label_for_completion(completion)
 82            }
 83            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_completion(completion),
 84            _ => None,
 85        }
 86    }
 87
 88    fn language_server_initialization_options(
 89        &mut self,
 90        language_server_id: &LanguageServerId,
 91        worktree: &zed::Worktree,
 92    ) -> Result<Option<serde_json::Value>> {
 93        let initialization_options =
 94            LspSettings::for_worktree(language_server_id.as_ref(), worktree)
 95                .ok()
 96                .and_then(|lsp_settings| lsp_settings.initialization_options.clone())
 97                .unwrap_or_default();
 98
 99        Ok(Some(serde_json::json!(initialization_options)))
100    }
101}
102
103zed::register_extension!(RubyExtension);