Set the working directory according to the editor file path (#14688)

Kernels now launch in the same directory as the script invoking them,
similar to notebook behavior.


![image](https://github.com/user-attachments/assets/def86308-bea4-4fa3-8211-132a282a5ecc)


Release Notes:

- N/A
This commit is contained in:
Kyle Kelley 2024-07-17 15:37:47 -07:00 committed by GitHub
parent f5f4578422
commit ba4fa17b83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 17 deletions

View File

@ -131,7 +131,7 @@ use std::{
mem, mem,
num::NonZeroU32, num::NonZeroU32,
ops::{ControlFlow, Deref, DerefMut, Not as _, Range, RangeInclusive}, ops::{ControlFlow, Deref, DerefMut, Not as _, Range, RangeInclusive},
path::Path, path::{Path, PathBuf},
rc::Rc, rc::Rc,
sync::Arc, sync::Arc,
time::{Duration, Instant}, time::{Duration, Instant},
@ -10386,6 +10386,22 @@ impl Editor {
cx.notify(); cx.notify();
} }
pub fn working_directory(&self, cx: &WindowContext) -> Option<PathBuf> {
if let Some(buffer) = self.buffer().read(cx).as_singleton() {
if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) {
if let Some(dir) = file.abs_path(cx).parent() {
return Some(dir.to_owned());
}
}
if let Some(project_path) = buffer.read(cx).project_path(cx) {
return Some(project_path.path.to_path_buf());
}
}
None
}
pub fn reveal_in_finder(&mut self, _: &RevealInFileManager, cx: &mut ViewContext<Self>) { pub fn reveal_in_finder(&mut self, _: &RevealInFileManager, cx: &mut ViewContext<Self>) {
if let Some(buffer) = self.buffer().read(cx).as_singleton() { if let Some(buffer) = self.buffer().read(cx).as_singleton() {
if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) { if let Some(file) = buffer.read(cx).file().and_then(|f| f.as_local()) {

View File

@ -171,6 +171,7 @@ pub struct RunningKernel {
_control_task: Task<anyhow::Result<()>>, _control_task: Task<anyhow::Result<()>>,
_routing_task: Task<anyhow::Result<()>>, _routing_task: Task<anyhow::Result<()>>,
connection_path: PathBuf, connection_path: PathBuf,
pub working_directory: PathBuf,
pub request_tx: mpsc::Sender<JupyterMessage>, pub request_tx: mpsc::Sender<JupyterMessage>,
pub execution_state: ExecutionState, pub execution_state: ExecutionState,
pub kernel_info: Option<KernelInfoReply>, pub kernel_info: Option<KernelInfoReply>,
@ -190,6 +191,7 @@ impl RunningKernel {
pub fn new( pub fn new(
kernel_specification: KernelSpecification, kernel_specification: KernelSpecification,
entity_id: EntityId, entity_id: EntityId,
working_directory: PathBuf,
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
cx: &mut AppContext, cx: &mut AppContext,
) -> Task<anyhow::Result<(Self, JupyterMessageChannel)>> { ) -> Task<anyhow::Result<(Self, JupyterMessageChannel)>> {
@ -220,7 +222,9 @@ impl RunningKernel {
fs.atomic_write(connection_path.clone(), content).await?; fs.atomic_write(connection_path.clone(), content).await?;
let mut cmd = kernel_specification.command(&connection_path)?; let mut cmd = kernel_specification.command(&connection_path)?;
let process = cmd let process = cmd
.current_dir(&working_directory)
// .stdout(Stdio::null()) // .stdout(Stdio::null())
// .stderr(Stdio::null()) // .stderr(Stdio::null())
.kill_on_drop(true) .kill_on_drop(true)
@ -301,6 +305,7 @@ impl RunningKernel {
Self { Self {
process, process,
request_tx, request_tx,
working_directory,
_shell_task, _shell_task,
_iopub_task, _iopub_task,
_control_task, _control_task,

View File

@ -208,9 +208,16 @@ impl RuntimePanel {
cx.notify(); cx.notify();
} }
// Gets the active selection in the editor or the current line pub fn snippet(
fn selection(&self, editor: View<Editor>, cx: &mut ViewContext<Self>) -> Range<Anchor> { &self,
editor: WeakView<Editor>,
cx: &mut ViewContext<Self>,
) -> Option<(String, Arc<Language>, Range<Anchor>)> {
let editor = editor.upgrade()?;
let editor = editor.read(cx); let editor = editor.read(cx);
let buffer = editor.buffer().read(cx).snapshot(cx);
let selection = editor.selections.newest::<usize>(cx); let selection = editor.selections.newest::<usize>(cx);
let multi_buffer_snapshot = editor.buffer().read(cx).snapshot(cx); let multi_buffer_snapshot = editor.buffer().read(cx).snapshot(cx);
@ -232,18 +239,7 @@ impl RuntimePanel {
selection.range() selection.range()
}; };
range.to_anchors(&multi_buffer_snapshot) let anchor_range = range.to_anchors(&multi_buffer_snapshot);
}
pub fn snippet(
&self,
editor: WeakView<Editor>,
cx: &mut ViewContext<Self>,
) -> Option<(String, Arc<Language>, Range<Anchor>)> {
let editor = editor.upgrade()?;
let buffer = editor.read(cx).buffer().read(cx).snapshot(cx);
let anchor_range = self.selection(editor, cx);
let selected_text = buffer let selected_text = buffer
.text_for_range(anchor_range.clone()) .text_for_range(anchor_range.clone())

View File

@ -19,7 +19,7 @@ use runtimelib::{
ExecuteRequest, InterruptRequest, JupyterMessage, JupyterMessageContent, ShutdownRequest, ExecuteRequest, InterruptRequest, JupyterMessage, JupyterMessageContent, ShutdownRequest,
}; };
use settings::Settings as _; use settings::Settings as _;
use std::{ops::Range, sync::Arc, time::Duration}; use std::{env::temp_dir, ops::Range, path::PathBuf, sync::Arc, time::Duration};
use theme::{ActiveTheme, ThemeSettings}; use theme::{ActiveTheme, ThemeSettings};
use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, Label}; use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, Label};
@ -144,6 +144,17 @@ impl EditorBlock {
} }
impl Session { impl Session {
pub fn working_directory(editor: WeakView<Editor>, cx: &WindowContext) -> PathBuf {
if let Some(working_directory) = editor
.upgrade()
.and_then(|editor| editor.read(cx).working_directory(cx))
{
working_directory
} else {
temp_dir()
}
}
pub fn new( pub fn new(
editor: WeakView<Editor>, editor: WeakView<Editor>,
fs: Arc<dyn Fs>, fs: Arc<dyn Fs>,
@ -151,7 +162,14 @@ impl Session {
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Self { ) -> Self {
let entity_id = editor.entity_id(); let entity_id = editor.entity_id();
let kernel = RunningKernel::new(kernel_specification.clone(), entity_id, fs.clone(), cx);
let kernel = RunningKernel::new(
kernel_specification.clone(),
entity_id,
Self::working_directory(editor.clone(), cx),
fs.clone(),
cx,
);
let pending_kernel = cx let pending_kernel = cx
.spawn(|this, mut cx| async move { .spawn(|this, mut cx| async move {