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