From 3d616214a5d31468af162894b8b2314b9ec75adb Mon Sep 17 00:00:00 2001 From: techwritescode <10032418+techwritescode@users.noreply.github.com> Date: Thu, 31 Jul 2025 16:55:55 -0500 Subject: [PATCH] Windows support fixes --- Cargo.lock | 7 +++++++ lsp/Cargo.toml | 1 + lsp/src/asm_server.rs | 20 +++++++++++--------- lsp/src/data/convert_uri.rs | 25 +++++++++++++++++++++++++ lsp/src/data/files.rs | 27 ++++++++++++++------------- lsp/src/data/mod.rs | 1 + lsp/src/definition.rs | 2 +- lsp/src/index_engine.rs | 12 ++++-------- 8 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 lsp/src/data/convert_uri.rs diff --git a/Cargo.lock b/Cargo.lock index ffce2df..effeada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,7 @@ dependencies = [ "tracing", "tracing-subscriber", "url", + "urlencoding", "uuid", "walkdir", ] @@ -1032,6 +1033,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8_iter" version = "1.0.4" diff --git a/lsp/Cargo.toml b/lsp/Cargo.toml index 0594030..28ea09d 100644 --- a/lsp/Cargo.toml +++ b/lsp/Cargo.toml @@ -20,4 +20,5 @@ lazy_static = "1.5.0" walkdir = "2.5.0" uuid = { version = "1.17.0", features = ["v4"] } url = "2.5.4" +urlencoding = "2.1.3" path-clean = "1.0.1" \ No newline at end of file diff --git a/lsp/src/asm_server.rs b/lsp/src/asm_server.rs index 7e374e8..306aa3d 100644 --- a/lsp/src/asm_server.rs +++ b/lsp/src/asm_server.rs @@ -31,14 +31,15 @@ use tower_lsp_server::lsp_types::{ WorkspaceServerCapabilities, }; use tower_lsp_server::{ - Client, LanguageServer, - jsonrpc::Result, - lsp_types::{ + jsonrpc::Result, lsp_types::{ DidChangeTextDocumentParams, DidOpenTextDocumentParams, GotoDefinitionParams, GotoDefinitionResponse, Hover, HoverParams, InitializeParams, InitializeResult, MarkedString, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind, Uri, }, + Client, + LanguageServer, }; +use crate::data::convert_uri::convert_uri; #[allow(dead_code)] pub struct Asm { @@ -235,13 +236,11 @@ impl LanguageServer for Asm { .expect("Failed to read config"); } - tokio::spawn(IndexEngine::crawl_fs( + IndexEngine::crawl_fs( self.index_engine.clone(), workspace_folder, self.client.clone(), - )) - .await - .unwrap(); + ).await; } } @@ -251,7 +250,10 @@ impl LanguageServer for Asm { async fn did_open(&self, params: DidOpenTextDocumentParams) { let mut state = self.state.lock().await; - let id = state.get_or_insert_source(params.text_document.uri, params.text_document.text); + let id = state.get_or_insert_source( + convert_uri(params.text_document.uri).unwrap(), + params.text_document.text, + ); drop(state); self.index(id).await; @@ -594,4 +596,4 @@ fn scope_to_symbol(scope: &Scope, file: &CacheFile) -> Option { } else { None } -} +} \ No newline at end of file diff --git a/lsp/src/data/convert_uri.rs b/lsp/src/data/convert_uri.rs new file mode 100644 index 0000000..71bfe71 --- /dev/null +++ b/lsp/src/data/convert_uri.rs @@ -0,0 +1,25 @@ +use std::str::FromStr; +use anyhow::anyhow; +use tower_lsp_server::lsp_types::Uri; +use urlencoding::encode; + +#[cfg(target_os = "windows")] +pub fn convert_uri(uri: Uri) -> anyhow::Result { + let segments = uri.path().segments(); + let mut segments = segments + .map(|segments| segments.to_string()) + .collect::>(); + + let drive_letter = segments[0].chars().next().unwrap(); + + let drive = format!("{}:", drive_letter.to_ascii_lowercase()); + segments[0] = encode(&drive).to_string(); + + let path = format!("file:///{}", segments.join("/")); + Uri::from_str(&path).map_err(|e| anyhow!(e)) +} + +#[cfg(not(target_os = "windows"))] +pub fn convert_uri(uri: Uri) -> anyhow::Result { + Ok(uri) +} \ No newline at end of file diff --git a/lsp/src/data/files.rs b/lsp/src/data/files.rs index 5db42f8..a287bb3 100644 --- a/lsp/src/data/files.rs +++ b/lsp/src/data/files.rs @@ -1,16 +1,19 @@ use crate::analysis::scope_analyzer; use crate::analysis::scope_analyzer::ScopeAnalyzer; use crate::cache_file::{CacheFile, Include, ResolvedInclude}; +use crate::data::convert_uri::convert_uri; use crate::data::indexing_state::IndexingState; use crate::data::path::diff_paths; use crate::data::symbol::{Symbol, SymbolType}; +use anyhow::anyhow; use codespan::{File, FileId, Position}; use parser::{ParseError, Token, TokenizerError}; use path_clean::PathClean; use std::collections::{HashMap, HashSet}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::str::FromStr; use tower_lsp_server::lsp_types::{Diagnostic, Range, Uri}; +use url::Url; pub enum IndexError { TokenizerError(TokenizerError), @@ -94,17 +97,22 @@ impl Files { return Ok(None); } - let parent = PathBuf::from_str(parent_uri.path().as_str())? + let parent = Url::from_str(parent_uri.as_str())? + .to_file_path() + .map_err(|_| anyhow!("Failed to create pathbuf"))? .parent() .ok_or_else(|| anyhow::anyhow!("parent folder not found"))? .join(path) .clean(); - let parent = Uri::from_str(url::Url::from_file_path(parent).unwrap().as_ref())?; + + let parent = convert_uri(Uri::from_str(Url::from_file_path(parent).unwrap().as_ref())?)?; let id = self .sources .iter() - .find_map(|(uri, id)| if *uri == parent { Some(*id) } else { None }); + .find_map(|(uri, id)| { + if uri.as_str() == parent.as_str() { Some(*id) } else { None } + }); Ok(Some(id.ok_or_else(|| anyhow::anyhow!("file not found"))?)) } @@ -143,15 +151,8 @@ impl Files { } pub fn resolve_imports_for_file(&self, parent: FileId) -> HashSet { - // eprintln!("Crawling {:?}", parent); let mut all_files = HashSet::new(); for include in self.get(parent).resolved_includes.iter() { - // eprintln!("Including {:?}", include); - // eprintln!( - // "Including {:?} from {:?}", - // state.files.get_uri(include.file).as_str(), - // state.files.get_uri(parent).as_str() - // ); if !all_files.contains(&include.file) && include.file != parent { all_files.extend(self.resolve_imports_for_file(include.file)); } @@ -236,6 +237,6 @@ fn is_includes_same(includes: &[Include], resolved_includes: &[ResolvedInclude]) return false; } } - + true -} \ No newline at end of file +} diff --git a/lsp/src/data/mod.rs b/lsp/src/data/mod.rs index 208a010..77d89c0 100644 --- a/lsp/src/data/mod.rs +++ b/lsp/src/data/mod.rs @@ -5,3 +5,4 @@ pub mod path; pub mod symbol; pub mod units; pub mod files; +pub mod convert_uri; diff --git a/lsp/src/definition.rs b/lsp/src/definition.rs index c5d0fa5..7a56cb9 100644 --- a/lsp/src/definition.rs +++ b/lsp/src/definition.rs @@ -42,7 +42,7 @@ impl Definition { id: FileId, position: Position, ) -> Result, Span)>, FileError> { - let file = &state.files.get(id); + let file = state.files.get(id); let units = state.units.find_related(id); if units.len() == 0 { // TODO: Not included diff --git a/lsp/src/index_engine.rs b/lsp/src/index_engine.rs index 0535511..ec4d0f5 100644 --- a/lsp/src/index_engine.rs +++ b/lsp/src/index_engine.rs @@ -1,4 +1,4 @@ -use crate::analysis::scope_analyzer::Scope; +use crate::data::convert_uri::convert_uri; use crate::data::files::Files; use crate::data::symbol::Symbol; use crate::state::State; @@ -9,12 +9,12 @@ use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; use tokio::sync::Mutex; -use tower_lsp_server::Client; use tower_lsp_server::lsp_types::request::WorkDoneProgressCreate; use tower_lsp_server::lsp_types::{ Diagnostic, InlayHintWorkspaceClientCapabilities, ProgressToken, Uri, WorkDoneProgressCreateParams, WorkspaceClientCapabilities, }; +use tower_lsp_server::Client; use uuid::Uuid; pub struct IndexEngine { @@ -73,9 +73,9 @@ impl IndexEngine { ((idx as f32) / (sources.len() as f32) * 100.0) as u32, ) .await; - let uri = Uri::from_str(url::Url::from_file_path(file).unwrap().as_ref()).unwrap(); + let uri = Uri::from_str(url::Url::from_file_path(file).unwrap().as_str()).unwrap(); let contents = std::fs::read_to_string(file).unwrap(); - let id = state.get_or_insert_source(uri, contents); + let id = state.get_or_insert_source(convert_uri(uri).unwrap(), contents); let file = state.files.index(id).await; diagnostics.insert(id, file.diagnostics); parsed_files.push(id); @@ -113,7 +113,6 @@ impl IndexEngine { } for id in parsed_files.iter() { - // let diags = IndexEngine::invalidate(&mut state, *id).await; state .publish_diagnostics( *id, @@ -138,10 +137,7 @@ impl IndexEngine { let file = state.files.get_mut(file); if resolved_imports.iter().ne(&file.resolved_includes) { - // eprintln!("Changed {:#?}", file.resolved_includes); file.resolved_includes = resolved_imports; - } else { - // eprintln!("No changes"); } diagnostics