@@ -177,6 +177,13 @@ impl PythonEnvKernelSpecification {
kernelspec: self.kernelspec.clone(),
}
}
+
+ pub fn is_uv(&self) -> bool {
+ matches!(
+ self.environment_kind.as_deref(),
+ Some("uv" | "uv (Workspace)")
+ )
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -87,6 +87,7 @@ pub fn install_ipykernel_and_assign(
let python_path = env_spec.path.clone();
let env_name = env_spec.name.clone();
+ let is_uv = env_spec.is_uv();
let env_spec = env_spec.clone();
struct IpykernelInstall;
@@ -109,11 +110,25 @@ pub fn install_ipykernel_and_assign(
let window_handle = window.window_handle();
let install_task = cx.background_spawn(async move {
- let output = util::command::new_command(python_path.to_string_lossy().as_ref())
- .args(&["-m", "pip", "install", "ipykernel"])
- .output()
- .await
- .context("failed to run pip install ipykernel")?;
+ let output = if is_uv {
+ util::command::new_command("uv")
+ .args(&[
+ "pip",
+ "install",
+ "ipykernel",
+ "--python",
+ &python_path.to_string_lossy(),
+ ])
+ .output()
+ .await
+ .context("failed to run uv pip install ipykernel")?
+ } else {
+ util::command::new_command(python_path.to_string_lossy().as_ref())
+ .args(&["-m", "pip", "install", "ipykernel"])
+ .output()
+ .await
+ .context("failed to run pip install ipykernel")?
+ };
if output.status.success() {
anyhow::Ok(())
@@ -146,6 +161,11 @@ pub fn install_ipykernel_and_assign(
window_handle
.update(cx, |_, window, cx| {
+ let store = ReplStore::global(cx);
+ store.update(cx, |store, cx| {
+ store.mark_ipykernel_installed(cx, &env_spec);
+ });
+
let updated_spec =
KernelSpecification::PythonEnv(PythonEnvKernelSpecification {
has_ipykernel: true,
@@ -13,8 +13,8 @@ use settings::{Settings, SettingsStore};
use util::rel_path::RelPath;
use crate::kernels::{
- Kernel, list_remote_kernelspecs, local_kernel_specifications, python_env_kernel_specifications,
- wsl_kernel_specifications,
+ Kernel, PythonEnvKernelSpecification, list_remote_kernelspecs, local_kernel_specifications,
+ python_env_kernel_specifications, wsl_kernel_specifications,
};
use crate::{JupyterSettings, KernelSpecification, Session};
@@ -136,6 +136,23 @@ impl ReplStore {
cx.notify();
}
+ pub fn mark_ipykernel_installed(
+ &mut self,
+ cx: &mut Context<Self>,
+ spec: &PythonEnvKernelSpecification,
+ ) {
+ for specs in self.kernel_specifications_for_worktree.values_mut() {
+ for kernel_spec in specs.iter_mut() {
+ if let KernelSpecification::PythonEnv(env_spec) = kernel_spec {
+ if env_spec == spec {
+ env_spec.has_ipykernel = true;
+ }
+ }
+ }
+ }
+ cx.notify();
+ }
+
pub fn refresh_python_kernelspecs(
&mut self,
worktree_id: WorktreeId,