1use std::sync::Arc;
8
9use serde::{Deserialize, Serialize};
10
11use crate::API::types::*;
12
13#[derive(Debug, Clone)]
15pub struct VSCodeAPI {
16 pub commands:Arc<Commands>,
18 pub window:Arc<Window>,
20 pub workspace:Arc<Workspace>,
22 pub languages:Arc<Languages>,
24 pub extensions:Arc<Extensions>,
26 pub env:Arc<Env>,
28}
29
30impl VSCodeAPI {
31 pub fn new() -> Self {
33 Self {
34 commands:Arc::new(Commands::new()),
35 window:Arc::new(Window::new()),
36 workspace:Arc::new(Workspace::new()),
37 languages:Arc::new(Languages::new()),
38 extensions:Arc::new(Extensions::new()),
39 env:Arc::new(Env::new()),
40 }
41 }
42}
43
44impl Default for VSCodeAPI {
45 fn default() -> Self { Self::new() }
46}
47
48#[derive(Debug, Clone)]
50pub struct Commands;
51
52impl Commands {
53pub fn new() -> Self { Self }
55
56 pub fn register_command(&self, command_id:String, callback:CommandCallback) -> Result<Command, String> {
58 Ok(Command { id:command_id.clone() })
59 }
60
61 pub async fn execute_command<T:serde::de::DeserializeOwned>(
63 &self,
64 command_id:String,
65 args:Vec<serde_json::Value>,
66 ) -> Result<T, String> {
67 Err(format!("Command not implemented: {}", command_id))
69 }
70}
71
72pub type CommandCallback = Box<dyn Fn(Vec<serde_json::Value>) -> Result<serde_json::Value, String> + Send + Sync>;
74
75#[derive(Debug, Clone)]
77pub struct Command {
78pub id:String,
80}
81
82#[derive(Debug, Clone)]
84pub struct Window;
85
86impl Window {
87pub fn new() -> Self { Self }
89
90 pub async fn show_information_message(&self, message:String) -> Result<String, String> {
92 Ok("OK".to_string())
94 }
95
96 pub async fn show_warning_message(&self, message:String) -> Result<String, String> {
98 Ok("OK".to_string())
100 }
101
102 pub async fn show_error_message(&self, message:String) -> Result<String, String> {
104 Ok("OK".to_string())
106 }
107
108 pub fn create_output_channel(&self, name:String) -> OutputChannel { OutputChannel::new(name) }
110}
111
112#[derive(Debug, Clone)]
114pub struct OutputChannel {
115name:String,
117}
118
119impl OutputChannel {
120pub fn new(name:String) -> Self { Self { name } }
126
127 pub fn append_line(&self, line:&str) {
129 tracing::info!("[{}] {}", self.name, line);
130 }
131
132 pub fn append(&self, value:&str) {
134 tracing::info!("[{}] {}", self.name, value);
135 }
136
137 pub fn show(&self) {
139 }
141
142 pub fn hide(&self) {
144 }
146
147 pub fn dispose(&self) {
149 }
151}
152
153#[derive(Debug, Clone)]
155pub struct Workspace;
156
157impl Workspace {
158pub fn new() -> Self { Self }
160
161 pub fn workspace_folders(&self) -> Vec<WorkspaceFolder> {
163 Vec::new()
165 }
166
167 pub fn get_configuration(&self, section:Option<String>) -> WorkspaceConfiguration {
169 WorkspaceConfiguration::new(section)
170 }
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct WorkspaceFolder {
176 pub uri:String,
178
179 pub name:String,
181
182 pub index:u32,
184}
185
186#[derive(Debug, Clone)]
188pub struct WorkspaceConfiguration {
189section:Option<String>,
191}
192
193impl WorkspaceConfiguration {
194pub fn new(section:Option<String>) -> Self { Self { section } }
200
201 pub fn get<T:serde::de::DeserializeOwned>(&self, key:String) -> Result<T, String> {
203 Err(format!("Configuration not implemented: {:?}", key))
205 }
206
207 pub fn has(&self, key:String) -> bool { false }
209
210 pub async fn update(&self, key:String, value:serde_json::Value) -> Result<(), String> {
212 Err(format!("Update configuration not implemented: {}", key))
214 }
215}
216
217#[derive(Debug, Clone)]
219pub struct Languages;
220
221impl Languages {
222pub fn new() -> Self { Self }
224
225 pub async fn register_completion_item_provider<T:CompletionItemProvider>(
227 &self,
228 _selector:DocumentSelector,
229 _provider:T,
230 _trigger_characters:Option<Vec<String>>,
231 ) -> Result<Disposable, String> {
232 Ok(Disposable::new())
233 }
234
235 pub fn create_diagnostic_collection(&self, name:Option<String>) -> DiagnosticCollection {
237 DiagnosticCollection::new(name)
238 }
239}
240
241#[derive(Debug, Clone, Serialize, Deserialize)]
243pub struct DocumentFilter {
244 pub language:Option<String>,
246
247 pub scheme:Option<String>,
249
250 pub pattern:Option<String>,
252}
253
254pub type DocumentSelector = Vec<DocumentFilter>;
256
257pub trait CompletionItemProvider: Send + Sync {
259fn provide_completion_items(
272&self,
273document:TextDocumentIdentifier,
274position:Position,
275context:CompletionContext,
276token:Option<String>,
277) -> Vec<CompletionItem>;
278}
279
280#[derive(Debug, Clone, Serialize, Deserialize)]
282pub struct CompletionContext {
283 #[serde(rename = "triggerKind")]
285 pub trigger_kind:CompletionTriggerKind,
286
287 #[serde(rename = "triggerCharacter")]
289 pub trigger_character:Option<String>,
290}
291
292#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
294pub enum CompletionTriggerKind {
295 #[serde(rename = "Invoke")]
297 Invoke = 0,
298
299 #[serde(rename = "TriggerCharacter")]
301 TriggerCharacter = 1,
302
303 #[serde(rename = "TriggerForIncompleteCompletions")]
305 TriggerForIncompleteCompletions = 2,
306}
307
308#[derive(Debug, Clone)]
310pub struct DiagnosticCollection {
311name:Option<String>,
313}
314
315impl DiagnosticCollection {
316pub fn new(name:Option<String>) -> Self { Self { name } }
322
323 pub fn set(&self, uri:String, diagnostics:Vec<Diagnostic>) {
325 }
327
328 pub fn delete(&self, uri:String) {
330 }
332
333 pub fn clear(&self) {
335 }
337
338 pub fn dispose(&self) {
340 }
342}
343
344#[derive(Debug, Clone)]
346pub struct Disposable;
347
348impl Disposable {
349pub fn new() -> Self { Self }
351
352pub fn dispose(&self) {
354}
356}
357
358#[derive(Debug, Clone)]
360pub struct Extensions;
361
362impl Extensions {
363pub fn new() -> Self { Self }
365
366 pub fn all(&self) -> Vec<Extension> { Vec::new() }
368
369 pub fn get_extension(&self, extension_id:String) -> Option<Extension> { None }
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize)]
375pub struct Extension {
376 pub id:String,
378
379 #[serde(rename = "extensionPath")]
381 pub extension_path:String,
382
383 pub is_active:bool,
385
386 #[serde(rename = "packageJSON")]
388 pub package_json:serde_json::Value,
389}
390
391#[derive(Debug, Clone)]
393pub struct Env;
394
395impl Env {
396pub fn new() -> Self { Self }
398
399 pub fn get_env_var(&self, name:String) -> Option<String> { std::env::var(name).ok() }
401
402 pub fn is_windows(&self) -> bool { cfg!(windows) }
404
405 pub fn is_mac(&self) -> bool { cfg!(target_os = "macos") }
407
408 pub fn is_linux(&self) -> bool { cfg!(target_os = "linux") }
410
411 pub fn app_name(&self) -> String { "VS Code".to_string() }
413
414 pub fn app_root(&self) -> Option<String> { std::env::var("VSCODE_APP_ROOT").ok() }
416}
417
418#[cfg(test)]
419mod tests {
420 use super::*;
421
422 #[test]
423 fn test_vscode_api_creation() {
424 let _api = VSCodeAPI::new();
425 }
427
428 #[test]
429 fn test_position_operations() {
430 let pos = Position::new(5, 10);
431 assert_eq!(pos.line, 5);
432 assert_eq!(pos.character, 10);
433 }
434
435 #[test]
436 fn test_output_channel() {
437 let channel = OutputChannel::new("test".to_string());
438 channel.append_line("test message");
439 }
440
441 #[test]
442 fn test_disposable() {
443 let disposable = Disposable::new();
444 disposable.dispose();
445 }
446}