Implement RunningKernel trait for native and remote kernels (#20934)
This PR introduces a unified interface for both native and remote kernels through the `RunningKernel` trait. When either the native kernel or the remote kernels are started, they return a `Box<dyn RunningKernel>` to make it easier to work with the session. As a bonus of this refactor, I've dropped some of the mpsc channels to instead opt for passing messages directly to `session.route(message)`. There was a lot of simplification of `Session` by moving responsibilities to `NativeRunningKernel`. No release notes yet until this is finalized. * [x] Detect remote kernelspecs from configured remote servers * [x] Launch kernel on demand For now, this allows you to set env vars `JUPYTER_SERVER` and `JUPYTER_TOKEN` to access a remote server. `JUPYTER_SERVER` should be a base path like `http://localhost:8888` or `https://notebooks.gesis.org/binder/jupyter/user/rubydata-binder-w6igpy4l/` Release Notes: - N/A
This commit is contained in:
parent
f74f670865
commit
72613b7668
8 changed files with 478 additions and 230 deletions
|
@ -34,6 +34,16 @@ pub struct KernelPickerDelegate {
|
|||
on_select: OnSelect,
|
||||
}
|
||||
|
||||
// Helper function to truncate long paths
|
||||
fn truncate_path(path: &SharedString, max_length: usize) -> SharedString {
|
||||
if path.len() <= max_length {
|
||||
path.to_string().into()
|
||||
} else {
|
||||
let truncated = path.chars().rev().take(max_length - 3).collect::<String>();
|
||||
format!("...{}", truncated.chars().rev().collect::<String>()).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PopoverTrigger> KernelSelector<T> {
|
||||
pub fn new(on_select: OnSelect, worktree_id: WorktreeId, trigger: T) -> Self {
|
||||
KernelSelector {
|
||||
|
@ -116,11 +126,25 @@ impl PickerDelegate for KernelPickerDelegate {
|
|||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
_cx: &mut ViewContext<Picker<Self>>,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let kernelspec = self.filtered_kernels.get(ix)?;
|
||||
|
||||
let is_selected = self.selected_kernelspec.as_ref() == Some(kernelspec);
|
||||
let icon = kernelspec.icon(cx);
|
||||
|
||||
let (name, kernel_type, path_or_url) = match kernelspec {
|
||||
KernelSpecification::Jupyter(_) => (kernelspec.name(), "Jupyter", None),
|
||||
KernelSpecification::PythonEnv(_) => (
|
||||
kernelspec.name(),
|
||||
"Python Env",
|
||||
Some(truncate_path(&kernelspec.path(), 42)),
|
||||
),
|
||||
KernelSpecification::Remote(_) => (
|
||||
kernelspec.name(),
|
||||
"Remote",
|
||||
Some(truncate_path(&kernelspec.path(), 42)),
|
||||
),
|
||||
};
|
||||
|
||||
Some(
|
||||
ListItem::new(ix)
|
||||
|
@ -128,25 +152,46 @@ impl PickerDelegate for KernelPickerDelegate {
|
|||
.spacing(ListItemSpacing::Sparse)
|
||||
.selected(selected)
|
||||
.child(
|
||||
v_flex()
|
||||
.min_w(px(600.))
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_0p5()
|
||||
.gap_3()
|
||||
.child(icon.color(Color::Default).size(IconSize::Medium))
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
.child(Label::new(kernelspec.name()).weight(FontWeight::MEDIUM))
|
||||
v_flex()
|
||||
.flex_grow()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(kernelspec.language())
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child(
|
||||
div().w_48().text_ellipsis().child(
|
||||
Label::new(name)
|
||||
.weight(FontWeight::MEDIUM)
|
||||
.size(LabelSize::Default),
|
||||
),
|
||||
)
|
||||
.when_some(path_or_url.clone(), |flex, path| {
|
||||
flex.text_ellipsis().child(
|
||||
Label::new(path)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Label::new(kernelspec.language())
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
Label::new(kernel_type)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Label::new(kernelspec.path())
|
||||
.size(LabelSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.when(is_selected, |item| {
|
||||
|
@ -199,7 +244,9 @@ impl<T: PopoverTrigger> RenderOnce for KernelSelector<T> {
|
|||
};
|
||||
|
||||
let picker_view = cx.new_view(|cx| {
|
||||
let picker = Picker::uniform_list(delegate, cx).max_height(Some(rems(20.).into()));
|
||||
let picker = Picker::uniform_list(delegate, cx)
|
||||
.width(rems(30.))
|
||||
.max_height(Some(rems(20.).into()));
|
||||
picker
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue