From b556a064e3707fdd478ed35e25b437ff7c242653 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Tue, 27 Oct 2026 21:06:46 +0800 Subject: [PATCH] fix(remote): Map Windows project paths onto run targets and order query history by time --- crates/ide-db/src/history.rs | 4 +++- crates/ide-remote/src/target.rs | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/ide-db/src/history.rs b/crates/ide-db/src/history.rs index 21213d3c2..cf88b970d 100644 --- a/crates/ide-db/src/history.rs +++ b/crates/ide-db/src/history.rs @@ -52,7 +52,9 @@ impl HistoryStore { let mut all = self.read(); let entries = all.entry(self.project.clone()).or_default().entry(source.to_owned()).or_default(); entries.retain(|e| e.text != text); - entries.insert(0, HistoryEntry { text: text.to_owned(), time }); + // By time, newest first: statements are recorded off the async threads, in any order. + let at = entries.iter().position(|e| e.time <= time).unwrap_or(entries.len()); + entries.insert(at, HistoryEntry { text: text.to_owned(), time }); entries.truncate(MAX_ENTRIES); self.write(&all) } diff --git a/crates/ide-remote/src/target.rs b/crates/ide-remote/src/target.rs index de85c3e76..670bbf5c8 100644 --- a/crates/ide-remote/src/target.rs +++ b/crates/ide-remote/src/target.rs @@ -60,14 +60,26 @@ impl RemoteCommand { /// `s` with the path `root` replaced by `remote` where it appears as a whole path /// (followed by a separator or the end of a path), not as the prefix of a longer name. +/// The rest of a Windows path after the root takes `/` separators too. fn replace_root(s: &str, root: &str, remote: &str) -> String { let mut out = String::with_capacity(s.len()); let mut rest = s; while let Some(i) = rest.find(root) { - let after = &rest[i + root.len()..]; + let mut after = &rest[i + root.len()..]; let whole = after.chars().next().is_none_or(|c| !(c.is_alphanumeric() || matches!(c, '_' | '-' | '.'))); out.push_str(&rest[..i]); - out.push_str(if whole { remote } else { root }); + if whole { + out.push_str(remote); + if root.contains('\\') { + let end = after + .find(|c: char| c.is_whitespace() || matches!(c, ';' | ',' | '"' | '\'')) + .unwrap_or(after.len()); + out.push_str(&after[..end].replace('\\', "/")); + after = &after[end..]; + } + } else { + out.push_str(root); + } rest = after; } out.push_str(rest); @@ -317,6 +329,8 @@ mod tests { } } + // Unix paths are not absolute on Windows (`tests/remote.rs` runs there). + #[cfg(unix)] #[test] fn maps_interpreters_paths_and_folders() { let target = RunTarget { python: "/opt/py/bin/python".into(), ..Default::default() }; @@ -348,5 +362,6 @@ mod tests { fn maps_the_root_only_as_a_whole_path() { assert_eq!(replace_root("/work/proj2/x:/work/proj/y", "/work/proj", "/srv"), "/work/proj2/x:/srv/y"); assert_eq!(replace_root("/work/proj", "/work/proj", "/srv"), "/srv"); + assert_eq!(replace_root(r"C:\p\src/a.py C:\p2", r"C:\p", "/srv"), r"/srv/src/a.py C:\p2"); } }