python: Re-land usage of source file path in toolchain picker (#31893)

This reverts commit 1e55e88c18.

Closes #ISSUE

Release Notes:

- Python toolchain selector now uses path to the closest pyproject.toml
as a basis for picking a toolchain. All files under the same
pyproject.toml (in filesystem hierarchy) will share a single virtual
environment. It is possible to have multiple Python virtual environments
selected for disjoint parts of the same project.
This commit is contained in:
Piotr Osiewicz 2025-06-02 18:29:06 +02:00 committed by GitHub
parent 2ebe16a52f
commit 9dd18e5ee1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 195 additions and 92 deletions

View file

@ -11,16 +11,17 @@ use std::{
borrow::Borrow,
collections::{BTreeMap, hash_map::Entry},
ops::ControlFlow,
path::Path,
sync::Arc,
};
use collections::HashMap;
use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Subscription};
use language::{LspAdapterDelegate, ManifestName, ManifestQuery};
use language::{ManifestDelegate, ManifestName, ManifestQuery};
pub use manifest_store::ManifestProviders;
use path_trie::{LabelPresence, RootPathTrie, TriePath};
use settings::{SettingsStore, WorktreeId};
use worktree::{Event as WorktreeEvent, Worktree};
use worktree::{Event as WorktreeEvent, Snapshot, Worktree};
use crate::{
ProjectPath,
@ -89,7 +90,7 @@ pub(crate) enum ManifestTreeEvent {
impl EventEmitter<ManifestTreeEvent> for ManifestTree {}
impl ManifestTree {
pub(crate) fn new(worktree_store: Entity<WorktreeStore>, cx: &mut App) -> Entity<Self> {
pub fn new(worktree_store: Entity<WorktreeStore>, cx: &mut App) -> Entity<Self> {
cx.new(|cx| Self {
root_points: Default::default(),
_subscriptions: [
@ -106,11 +107,11 @@ impl ManifestTree {
worktree_store,
})
}
fn root_for_path(
pub(crate) fn root_for_path(
&mut self,
ProjectPath { worktree_id, path }: ProjectPath,
manifests: &mut dyn Iterator<Item = ManifestName>,
delegate: Arc<dyn LspAdapterDelegate>,
delegate: Arc<dyn ManifestDelegate>,
cx: &mut App,
) -> BTreeMap<ManifestName, ProjectPath> {
debug_assert_eq!(delegate.worktree_id(), worktree_id);
@ -218,3 +219,26 @@ impl ManifestTree {
}
}
}
pub(crate) struct ManifestQueryDelegate {
worktree: Snapshot,
}
impl ManifestQueryDelegate {
pub fn new(worktree: Snapshot) -> Self {
Self { worktree }
}
}
impl ManifestDelegate for ManifestQueryDelegate {
fn exists(&self, path: &Path, is_dir: Option<bool>) -> bool {
self.worktree.entry_for_path(path).map_or(false, |entry| {
is_dir.map_or(true, |is_required_to_be_dir| {
is_required_to_be_dir == entry.is_dir()
})
})
}
fn worktree_id(&self) -> WorktreeId {
self.worktree.id()
}
}