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);