1mod language_servers;
2
3use zed::lsp::{Completion, Symbol};
4use zed::{serde_json, CodeLabel, LanguageServerId};
5use zed_extension_api::{self as zed, Result};
6
7use crate::language_servers::{ElixirLs, Lexical, NextLs};
8
9struct ElixirExtension {
10 elixir_ls: Option<ElixirLs>,
11 next_ls: Option<NextLs>,
12 lexical: Option<Lexical>,
13}
14
15impl zed::Extension for ElixirExtension {
16 fn new() -> Self {
17 Self {
18 elixir_ls: None,
19 next_ls: None,
20 lexical: None,
21 }
22 }
23
24 fn language_server_command(
25 &mut self,
26 language_server_id: &LanguageServerId,
27 worktree: &zed::Worktree,
28 ) -> Result<zed::Command> {
29 match language_server_id.as_ref() {
30 ElixirLs::LANGUAGE_SERVER_ID => {
31 let elixir_ls = self.elixir_ls.get_or_insert_with(|| ElixirLs::new());
32
33 Ok(zed::Command {
34 command: elixir_ls.language_server_binary_path(language_server_id, worktree)?,
35 args: vec![],
36 env: Default::default(),
37 })
38 }
39 NextLs::LANGUAGE_SERVER_ID => {
40 let next_ls = self.next_ls.get_or_insert_with(|| NextLs::new());
41
42 Ok(zed::Command {
43 command: next_ls.language_server_binary_path(language_server_id, worktree)?,
44 args: vec!["--stdio".to_string()],
45 env: Default::default(),
46 })
47 }
48 Lexical::LANGUAGE_SERVER_ID => {
49 let lexical = self.lexical.get_or_insert_with(|| Lexical::new());
50
51 Ok(zed::Command {
52 command: lexical.language_server_binary_path(language_server_id, worktree)?,
53 args: vec![],
54 env: Default::default(),
55 })
56 }
57 language_server_id => Err(format!("unknown language server: {language_server_id}")),
58 }
59 }
60
61 fn label_for_completion(
62 &self,
63 language_server_id: &LanguageServerId,
64 completion: Completion,
65 ) -> Option<CodeLabel> {
66 match language_server_id.as_ref() {
67 ElixirLs::LANGUAGE_SERVER_ID => {
68 self.elixir_ls.as_ref()?.label_for_completion(completion)
69 }
70 NextLs::LANGUAGE_SERVER_ID => self.next_ls.as_ref()?.label_for_completion(completion),
71 Lexical::LANGUAGE_SERVER_ID => self.lexical.as_ref()?.label_for_completion(completion),
72 _ => None,
73 }
74 }
75
76 fn label_for_symbol(
77 &self,
78 language_server_id: &LanguageServerId,
79 symbol: Symbol,
80 ) -> Option<CodeLabel> {
81 match language_server_id.as_ref() {
82 ElixirLs::LANGUAGE_SERVER_ID => self.elixir_ls.as_ref()?.label_for_symbol(symbol),
83 NextLs::LANGUAGE_SERVER_ID => self.next_ls.as_ref()?.label_for_symbol(symbol),
84 Lexical::LANGUAGE_SERVER_ID => self.lexical.as_ref()?.label_for_symbol(symbol),
85 _ => None,
86 }
87 }
88
89 fn language_server_initialization_options(
90 &mut self,
91 language_server_id: &LanguageServerId,
92 _worktree: &zed::Worktree,
93 ) -> Result<Option<serde_json::Value>> {
94 match language_server_id.as_ref() {
95 NextLs::LANGUAGE_SERVER_ID => Ok(Some(serde_json::json!({
96 "experimental": {
97 "completions": {
98 "enable": true
99 }
100 }
101 }))),
102 _ => Ok(None),
103 }
104 }
105
106 fn language_server_workspace_configuration(
107 &mut self,
108 language_server_id: &LanguageServerId,
109 worktree: &zed::Worktree,
110 ) -> Result<Option<serde_json::Value>> {
111 match language_server_id.as_ref() {
112 ElixirLs::LANGUAGE_SERVER_ID => {
113 if let Some(elixir_ls) = self.elixir_ls.as_mut() {
114 return elixir_ls.language_server_workspace_configuration(worktree);
115 }
116 }
117 _ => (),
118 }
119
120 Ok(None)
121 }
122}
123
124zed::register_extension!(ElixirExtension);