Skip to main content

oxc_zed/
oxc.rs

1mod lsp;
2mod oxfmt;
3mod oxlint;
4
5use crate::lsp::{OXFMT_SERVER_ID, OXLINT_SERVER_ID, ZedLspSupport};
6use crate::oxfmt::ZedOxfmtLsp;
7use crate::oxlint::ZedOxlintLsp;
8use log::Level;
9use serde_json::Value;
10use simple_logger::init_with_level;
11use std::sync::{Arc, RwLock};
12use zed_extension_api::{
13    Command, Extension, LanguageServerId, Result, Worktree, register_extension,
14    serde_json::{self},
15};
16
17struct OxcExtension {
18    oxfmt_lsp: Arc<RwLock<ZedOxfmtLsp>>,
19    oxlint_lsp: Arc<RwLock<ZedOxlintLsp>>,
20}
21
22impl OxcExtension {
23    fn is_oxfmt_language_server(&self, language_server_id: &LanguageServerId) -> bool {
24        language_server_id.as_ref() == OXFMT_SERVER_ID
25    }
26
27    fn is_oxlint_language_server(&self, language_server_id: &LanguageServerId) -> bool {
28        language_server_id.as_ref() == OXLINT_SERVER_ID
29    }
30
31    fn update_oxfmt_language_server_if_needed(
32        &self,
33        language_server_id: &LanguageServerId,
34        worktree: &Worktree,
35    ) -> Result<()> {
36        let zed_oxfmt_lsp = self.oxfmt_lsp.read().unwrap();
37        if !zed_oxfmt_lsp.exe_exists(worktree)? {
38            zed_oxfmt_lsp.update_extension_language_server_if_outdated(language_server_id)?;
39        }
40        Ok(())
41    }
42
43    fn update_oxlint_language_server_if_needed(
44        &self,
45        language_server_id: &LanguageServerId,
46        worktree: &Worktree,
47    ) -> Result<()> {
48        let zed_oxlint_lsp = self.oxlint_lsp.read().unwrap();
49        if !zed_oxlint_lsp.exe_exists(worktree)? {
50            zed_oxlint_lsp.update_extension_language_server_if_outdated(language_server_id)?;
51        }
52        Ok(())
53    }
54}
55
56impl Extension for OxcExtension {
57    fn new() -> Self
58    where
59        Self: Sized,
60    {
61        init_with_level(Level::Debug).unwrap();
62
63        Self {
64            oxfmt_lsp: Arc::new(RwLock::new(ZedOxfmtLsp::new())),
65            oxlint_lsp: Arc::new(RwLock::new(ZedOxlintLsp::new())),
66        }
67    }
68
69    fn language_server_command(
70        &mut self,
71        language_server_id: &LanguageServerId,
72        worktree: &Worktree,
73    ) -> Result<Command> {
74        if self.is_oxfmt_language_server(language_server_id) {
75            self.update_oxfmt_language_server_if_needed(language_server_id, worktree)?;
76
77            return self
78                .oxfmt_lsp
79                .read()
80                .unwrap()
81                .language_server_command(language_server_id, worktree);
82        }
83
84        if self.is_oxlint_language_server(language_server_id) {
85            self.update_oxlint_language_server_if_needed(language_server_id, worktree)?;
86
87            return self
88                .oxlint_lsp
89                .read()
90                .unwrap()
91                .language_server_command(language_server_id, worktree);
92        }
93
94        Err(format!(
95            "Unsupported language server id: {language_server_id:?}"
96        ))
97    }
98
99    fn language_server_initialization_options(
100        &mut self,
101        language_server_id: &LanguageServerId,
102        worktree: &Worktree,
103    ) -> Result<Option<Value>> {
104        if self.is_oxfmt_language_server(language_server_id) {
105            return self
106                .oxfmt_lsp
107                .read()
108                .unwrap()
109                .language_server_initialization_options(language_server_id, worktree);
110        }
111
112        if self.is_oxlint_language_server(language_server_id) {
113            return self
114                .oxlint_lsp
115                .read()
116                .unwrap()
117                .language_server_initialization_options(language_server_id, worktree);
118        }
119
120        Err(format!(
121            "Unsupported language server id: {language_server_id:?}"
122        ))
123    }
124
125    fn language_server_workspace_configuration(
126        &mut self,
127        language_server_id: &LanguageServerId,
128        worktree: &Worktree,
129    ) -> Result<Option<Value>> {
130        if self.is_oxfmt_language_server(language_server_id) {
131            return self
132                .oxfmt_lsp
133                .read()
134                .unwrap()
135                .language_server_workspace_configuration(language_server_id, worktree);
136        }
137
138        if self.is_oxlint_language_server(language_server_id) {
139            return self
140                .oxlint_lsp
141                .read()
142                .unwrap()
143                .language_server_workspace_configuration(language_server_id, worktree);
144        }
145
146        Err(format!(
147            "Unsupported language server id: {language_server_id:?}"
148        ))
149    }
150}
151
152register_extension!(OxcExtension);