Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions server/src/core/file_mgr.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use lsp_types::notification::{Notification, PublishDiagnostics};
use ropey::Rope;
use ruff_python_ast::{ModModule, PySourceType, Stmt};
use ruff_python_parser::{Parsed, Token, TokenKind};
use lsp_types::{Diagnostic, DiagnosticSeverity, MessageType, NumberOrString, Position, PublishDiagnosticsParams, Range, TextDocumentContentChangeEvent};
use lsp_types::notification::{Notification, PublishDiagnostics};
use tracing::{error, warn};
use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use std::sync::{atomic::{AtomicBool, Ordering}, Arc, OnceLock};
use std::{collections::HashMap, fs};
use crate::core::config::{DiagnosticFilter, DiagnosticFilterPathType};
use crate::core::diagnostics::{create_diagnostic, DiagnosticCode, DiagnosticSetting};
Expand All @@ -24,6 +24,13 @@ use ruff_text_size::{Ranged, TextRange};

use super::odoo::SyncOdoo;

// Global static for legacy UNC path detection
pub static LEGACY_UNC_PATHS: OnceLock<AtomicBool> = OnceLock::new();

pub fn legacy_unc_paths() -> &'static AtomicBool {
LEGACY_UNC_PATHS.get_or_init(|| AtomicBool::new(false))
}

#[derive(Debug, PartialEq, Clone)]
pub enum NoqaInfo {
None,
Expand Down Expand Up @@ -616,18 +623,37 @@ impl FileMgr {
if cfg!(windows) {
slash = "/";
}
let pre_uri = match url::Url::parse(&format!("file://{}{}", slash, s)) {
Ok(pre_uri) => pre_uri,
// If the path starts with \\\\, we want to remove it and also set slash to empty string
// Such that we have file://wsl.localhost/<path> for example
// For normal paths we do want file:///C:/...
// For some editors like PyCharm they use the legacy windows UNC urls so we have file:////wsl.localhost/<path>
let (replaced, unc) = if s.starts_with("\\\\") {
slash = "";
(s.replacen("\\\\", "", 1), true)
} else {
(s.clone(), false)
};
// Use legacy UNC flag to determine if we need four slashes
let mut pre_uri = match url::Url::parse(&format!("file://{}{}", slash, replaced)) {
Ok(pre_uri) => pre_uri.to_string(),
Err(err) => panic!("unable to transform pathname to uri: {s}, {}", err)
};
match lsp_types::Uri::from_str(pre_uri.as_str()) {
if unc && legacy_unc_paths().load(Ordering::Relaxed){
pre_uri = pre_uri.replace("file://", "file:////");
}
match lsp_types::Uri::from_str(&pre_uri) {
Ok(url) => url,
Err(err) => panic!("unable to transform pathname to uri: {s}, {}", err)
}
}

pub fn uri2pathname(s: &str) -> String {
if let Ok(url) = url::Url::parse(s) {
// Detect legacy UNC path (file:////)
if s.starts_with("file:////") {
legacy_unc_paths().store(true, Ordering::Relaxed);
}
let str_repr = s.replace("file:////", "file://");
if let Ok(url) = url::Url::parse(&str_repr) {
if let Ok(url) = url.to_file_path() {
return url.sanitize();
}
Expand Down
14 changes: 10 additions & 4 deletions server/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::{collections::HashMap, fs::{self, DirEntry}, path::{Path, PathBuf}, str::FromStr, sync::LazyLock};
use crate::core::file_mgr::legacy_unc_paths;
use path_slash::{PathBufExt, PathExt};
use regex::Regex;
use ruff_text_size::TextSize;
use std::process::Command;
use std::sync::atomic::Ordering;
use std::{collections::HashMap, fs::{self, DirEntry}, path::{Path, PathBuf}, str::FromStr, sync::LazyLock};

use crate::{constants::Tree, oyarn};

Expand Down Expand Up @@ -135,12 +137,16 @@ pub trait ToFilePath {
}

impl ToFilePath for lsp_types::Uri {

fn to_file_path(&self) -> Result<PathBuf, ()> {
let url = url::Url::from_str(self.as_str()).map_err(|_| ())?;
let s = self.as_str();
// Detect legacy UNC path (file:////)
if s.starts_with("file:////") {
legacy_unc_paths().store(true, Ordering::Relaxed);
}
let str_repr = s.replace("file:////", "file://");
let url = url::Url::from_str(&str_repr).map_err(|_| ())?;
url.to_file_path()
}

}

pub trait PathSanitizer {
Expand Down