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