diff --git a/crates/djls-server/src/server.rs b/crates/djls-server/src/server.rs index aa401ef..f14ee40 100644 --- a/crates/djls-server/src/server.rs +++ b/crates/djls-server/src/server.rs @@ -2,7 +2,6 @@ use std::future::Future; use std::sync::Arc; use tokio::sync::RwLock; -use serde_json; use tower_lsp_server::jsonrpc::Result as LspResult; use tower_lsp_server::lsp_types::CompletionOptions; use tower_lsp_server::lsp_types::CompletionParams; @@ -282,31 +281,28 @@ impl LanguageServer for DjangoLanguageServer { } async fn execute_command(&self, params: ExecuteCommandParams) -> LspResult> { - match params.command.as_str() { - "djls/dumpState" => { - tracing::info!("Executing djls/dumpState command"); - - // Check if debug mode is enabled - if std::env::var("DJLS_DEBUG").is_err() { - tracing::warn!("djls/dumpState command requires DJLS_DEBUG environment variable"); - return Ok(Some(serde_json::json!({ - "error": "Debug mode not enabled. Set DJLS_DEBUG environment variable." - }))); - } + if params.command.as_str() == "djls/dumpState" { + tracing::info!("Executing djls/dumpState command"); - let result = self.with_session(|session| { - session.dump_debug_state() - }).await; + // Check if debug mode is enabled + if std::env::var("DJLS_DEBUG").is_err() { + tracing::warn!("djls/dumpState command requires DJLS_DEBUG environment variable"); + return Ok(Some(serde_json::json!({ + "error": "Debug mode not enabled. Set DJLS_DEBUG environment variable." + }))); + } - Ok(Some(serde_json::json!({ - "success": true, - "message": result - }))) - } - _ => { - tracing::warn!("Unknown command: {}", params.command); - Ok(None) - } + let result = self.with_session(|session| { + session.dump_debug_state() + }).await; + + Ok(Some(serde_json::json!({ + "success": true, + "message": result + }))) + } else { + tracing::warn!("Unknown command: {}", params.command); + Ok(None) } } diff --git a/crates/djls-server/src/session.rs b/crates/djls-server/src/session.rs index 83027f0..6638bcf 100644 --- a/crates/djls-server/src/session.rs +++ b/crates/djls-server/src/session.rs @@ -3,7 +3,6 @@ use djls_project::DjangoProject; use salsa::StorageHandle; use tower_lsp_server::lsp_types::ClientCapabilities; use tower_lsp_server::lsp_types::InitializeParams; -use serde_json; use crate::db::ServerDatabase; use crate::workspace::Store; @@ -112,7 +111,7 @@ impl Session { let timestamp: DateTime = Utc::now(); let filename = format!("djls-debug-state-{}.json", timestamp.format("%Y%m%d-%H%M%S")); - + let debug_info = serde_json::json!({ "timestamp": timestamp.to_rfc3339(), "vfs": self.documents.debug_vfs_state(), @@ -124,13 +123,13 @@ impl Session { }); match fs::write(&filename, serde_json::to_string_pretty(&debug_info).unwrap_or_else(|_| "{}".to_string())) { - Ok(_) => { + Ok(()) => { tracing::info!("Debug state dumped to: {}", filename); - format!("Debug state written to: {}", filename) + format!("Debug state written to: {filename}") } Err(e) => { tracing::error!("Failed to write debug state: {}", e); - format!("Failed to write debug state: {}", e) + format!("Failed to write debug state: {e}") } } } diff --git a/crates/djls-server/src/workspace/document.rs b/crates/djls-server/src/workspace/document.rs index c671c7e..c41ab07 100644 --- a/crates/djls-server/src/workspace/document.rs +++ b/crates/djls-server/src/workspace/document.rs @@ -117,4 +117,3 @@ pub struct TemplateTagContext { pub closing_brace: ClosingBrace, pub needs_leading_space: bool, } - diff --git a/crates/djls-server/src/workspace/fs.rs b/crates/djls-server/src/workspace/fs.rs index 86b81dd..91f05df 100644 --- a/crates/djls-server/src/workspace/fs.rs +++ b/crates/djls-server/src/workspace/fs.rs @@ -168,9 +168,9 @@ impl FileSystem { } } -/// Implementation of the `vfs::FileSystem` trait for VfsPath compatibility. +/// Implementation of the `vfs::FileSystem` trait for `VfsPath` compatibility. /// -/// This trait implementation allows our custom FileSystem to be used with VfsPath +/// This trait implementation allows our custom `FileSystem` to be used with `VfsPath` /// while maintaining the dual-layer architecture. All operations respect the /// memory-over-physical priority, ensuring LSP semantics are preserved even when /// accessed through the generic VFS interface. diff --git a/crates/djls-server/src/workspace/store.rs b/crates/djls-server/src/workspace/store.rs index 22b23de..3f6ead7 100644 --- a/crates/djls-server/src/workspace/store.rs +++ b/crates/djls-server/src/workspace/store.rs @@ -1,7 +1,6 @@ use super::fs::FileSystem; use std::collections::HashMap; use std::path::PathBuf; -use serde_json; use anyhow::anyhow; use anyhow::Result; @@ -48,7 +47,7 @@ impl Store { root_path, }) } - + /// Check if a URI represents a file within the workspace fn is_workspace_file(&self, uri: &tower_lsp_server::lsp_types::Uri) -> bool { if let Some(path) = uri_to_pathbuf(uri) { @@ -65,7 +64,7 @@ impl Store { // Silently ignore files outside workspace return; } - + let uri = params.text_document.uri.to_string(); let version = params.text_document.version; let content = ¶ms.text_document.text; @@ -79,7 +78,7 @@ impl Store { &relative_path.to_string_lossy(), content ) { - eprintln!("Warning: Failed to write file to VFS: {}", e); + eprintln!("Warning: Failed to write file to VFS: {e}"); // Continue with normal processing despite VFS error } } @@ -101,7 +100,7 @@ impl Store { // Return Ok to avoid errors for files outside workspace return Ok(()); } - + let uri = params.text_document.uri.as_str().to_string(); let version = params.text_document.version; @@ -109,7 +108,7 @@ impl Store { if let Some(absolute_path) = uri_to_pathbuf(¶ms.text_document.uri) { if let Ok(relative_path) = absolute_path.strip_prefix(&self.root_path) { let relative_path_str = relative_path.to_string_lossy(); - + // Read current content from VFS (single source of truth) let current_content = self.vfs.read_to_string(&relative_path_str) .map_err(|e| anyhow!("Failed to read from VFS: {}", e))?; @@ -119,7 +118,7 @@ impl Store { // Write updated content back to VFS if let Err(e) = self.vfs.write_string(&relative_path_str, &updated_content) { - eprintln!("Warning: Failed to write to VFS: {}", e); + eprintln!("Warning: Failed to write to VFS: {e}"); } // Update document metadata (just version) @@ -143,10 +142,10 @@ impl Store { if let Some(absolute_path) = uri_to_pathbuf(¶ms.text_document.uri) { if let Ok(relative_path) = absolute_path.strip_prefix(&self.root_path) { let relative_path_str = relative_path.to_string_lossy(); - + // Discard any unsaved changes in VFS (clean up memory layer) if let Err(e) = self.vfs.discard_changes(&relative_path_str) { - eprintln!("Warning: Failed to discard VFS changes on close: {}", e); + eprintln!("Warning: Failed to discard VFS changes on close: {e}"); // Continue with document removal despite VFS error } } @@ -168,10 +167,10 @@ impl Store { if let Some(absolute_path) = uri_to_pathbuf(¶ms.text_document.uri) { if let Ok(relative_path) = absolute_path.strip_prefix(&self.root_path) { let relative_path_str = relative_path.to_string_lossy(); - + // Discard changes in VFS (clear memory layer so reads return disk content) if let Err(e) = self.vfs.discard_changes(&relative_path_str) { - eprintln!("Warning: Failed to discard VFS changes on save: {}", e); + eprintln!("Warning: Failed to discard VFS changes on save: {e}"); // Continue normally - this is not a critical error } } @@ -180,7 +179,7 @@ impl Store { Ok(()) } - /// Apply text changes to content (similar to TextDocument::with_changes but for strings) + /// Apply text changes to content (similar to `TextDocument::with_changes` but for strings) fn apply_changes_to_content( &self, mut content: String, @@ -190,7 +189,7 @@ impl Store { if let Some(range) = change.range { // Incremental change with range let index = LineIndex::new(&content); - + if let (Some(start_offset), Some(end_offset)) = ( index.offset(range.start).map(|o| o as usize), index.offset(range.end).map(|o| o as usize), @@ -277,7 +276,7 @@ impl Store { if let Some(absolute_path) = uri_to_pathbuf(&parsed_uri) { if let Ok(relative_path) = absolute_path.strip_prefix(&self.root_path) { let relative_path_str = relative_path.to_string_lossy(); - + // Try to read from VFS first (includes unsaved changes) match self.vfs.read_to_string(&relative_path_str) { Ok(vfs_content) => vfs_content, @@ -338,19 +337,19 @@ impl Store { } } - /// Debug method to expose VFS state (only enabled with DJLS_DEBUG) + /// Debug method to expose VFS state (only enabled with `DJLS_DEBUG`) pub fn debug_vfs_state(&self) -> serde_json::Value { use std::collections::HashMap; - + // Get memory layer contents by trying to read all known documents let mut memory_layer = HashMap::new(); - + for uri_str in self.documents.keys() { if let Ok(uri) = uri_str.parse::() { if let Some(absolute_path) = super::utils::uri_to_pathbuf(&uri) { if let Ok(relative_path) = absolute_path.strip_prefix(&self.root_path) { let relative_path_str = relative_path.to_string_lossy(); - + // Try to read from VFS - this will show us if there's content in memory layer if let Ok(content) = self.vfs.read_to_string(&relative_path_str) { memory_layer.insert(relative_path_str.to_string(), content); @@ -359,7 +358,7 @@ impl Store { } } } - + serde_json::json!({ "memory_layer_files": memory_layer, "physical_root": self.root_path.display().to_string() @@ -405,19 +404,19 @@ impl Store { }) } - /// Debug method to expose Store state (only enabled with DJLS_DEBUG) + /// Debug method to expose Store state (only enabled with `DJLS_DEBUG`) pub fn debug_store_state(&self) -> serde_json::Value { use std::collections::HashMap; - + let mut documents_info = HashMap::new(); - - for (uri, _doc) in &self.documents { + + for uri in self.documents.keys() { documents_info.insert(uri.clone(), serde_json::json!({ "version": self.versions.get(uri), "tracked": true })); } - + serde_json::json!({ "documents": documents_info, "document_count": self.documents.len(),