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                solargraph.language_server_command(language_server_id, worktree)
34            }
35            RubyLsp::LANGUAGE_SERVER_ID => {
36                let ruby_lsp = self.ruby_lsp.get_or_insert_with(|| RubyLsp::new());
37                ruby_lsp.language_server_command(language_server_id, worktree)
38            }
39            Rubocop::LANGUAGE_SERVER_ID => {
40                let rubocop = self.rubocop.get_or_insert_with(|| Rubocop::new());
41                rubocop.language_server_command(language_server_id, worktree)
42            }
43            language_server_id => Err(format!("unknown language server: {language_server_id}")),
44        }
45    }
46
47    fn label_for_symbol(
48        &self,
49        language_server_id: &LanguageServerId,
50        symbol: Symbol,
51    ) -> Option<CodeLabel> {
52        match language_server_id.as_ref() {
53            Solargraph::LANGUAGE_SERVER_ID => self.solargraph.as_ref()?.label_for_symbol(symbol),
54            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_symbol(symbol),
55            _ => None,
56        }
57    }
58
59    fn label_for_completion(
60        &self,
61        language_server_id: &LanguageServerId,
62        completion: Completion,
63    ) -> Option<CodeLabel> {
64        match language_server_id.as_ref() {
65            Solargraph::LANGUAGE_SERVER_ID => {
66                self.solargraph.as_ref()?.label_for_completion(completion)
67            }
68            RubyLsp::LANGUAGE_SERVER_ID => self.ruby_lsp.as_ref()?.label_for_completion(completion),
69            _ => None,
70        }
71    }
72
73    fn language_server_initialization_options(
74        &mut self,
75        language_server_id: &LanguageServerId,
76        worktree: &zed::Worktree,
77    ) -> Result<Option<serde_json::Value>> {
78        let initialization_options =
79            LspSettings::for_worktree(language_server_id.as_ref(), worktree)
80                .ok()
81                .and_then(|lsp_settings| lsp_settings.initialization_options.clone())
82                .unwrap_or_default();
83
84        Ok(Some(serde_json::json!(initialization_options)))
85    }
86}
87
88zed::register_extension!(RubyExtension);