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 let lexical_binary =
51 lexical.language_server_binary(language_server_id, worktree)?;
52
53 Ok(zed::Command {
54 command: lexical_binary.path,
55 args: lexical_binary.args.unwrap_or_default(),
56 env: Default::default(),
57 })
58 }
59 language_server_id => Err(format!("unknown language server: {language_server_id}")),
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 ElixirLs::LANGUAGE_SERVER_ID => {
70 self.elixir_ls.as_ref()?.label_for_completion(completion)
71 }
72 NextLs::LANGUAGE_SERVER_ID => self.next_ls.as_ref()?.label_for_completion(completion),
73 Lexical::LANGUAGE_SERVER_ID => self.lexical.as_ref()?.label_for_completion(completion),
74 _ => None,
75 }
76 }
77
78 fn label_for_symbol(
79 &self,
80 language_server_id: &LanguageServerId,
81 symbol: Symbol,
82 ) -> Option<CodeLabel> {
83 match language_server_id.as_ref() {
84 ElixirLs::LANGUAGE_SERVER_ID => self.elixir_ls.as_ref()?.label_for_symbol(symbol),
85 NextLs::LANGUAGE_SERVER_ID => self.next_ls.as_ref()?.label_for_symbol(symbol),
86 Lexical::LANGUAGE_SERVER_ID => self.lexical.as_ref()?.label_for_symbol(symbol),
87 _ => None,
88 }
89 }
90
91 fn language_server_initialization_options(
92 &mut self,
93 language_server_id: &LanguageServerId,
94 _worktree: &zed::Worktree,
95 ) -> Result<Option<serde_json::Value>> {
96 match language_server_id.as_ref() {
97 NextLs::LANGUAGE_SERVER_ID => Ok(Some(serde_json::json!({
98 "experimental": {
99 "completions": {
100 "enable": true
101 }
102 }
103 }))),
104 _ => Ok(None),
105 }
106 }
107
108 fn language_server_workspace_configuration(
109 &mut self,
110 language_server_id: &LanguageServerId,
111 worktree: &zed::Worktree,
112 ) -> Result<Option<serde_json::Value>> {
113 if language_server_id.as_ref() == ElixirLs::LANGUAGE_SERVER_ID {
114 if let Some(elixir_ls) = self.elixir_ls.as_mut() {
115 return elixir_ls.language_server_workspace_configuration(worktree);
116 }
117 }
118
119 Ok(None)
120 }
121}
122
123zed::register_extension!(ElixirExtension);