From cf89604fb5ca8880824e0d7e25b049b8c45c1ece Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 4 Oct 2024 22:33:59 +0300 Subject: [PATCH] Unite remote and local task variables This fixes gutter task runnables --- crates/editor/src/editor.rs | 27 ++++++++++--------- crates/editor/src/tasks.rs | 10 +++---- crates/project/src/project.rs | 1 + crates/project/src/task_store.rs | 45 +++++++++++++++++++++++++------- crates/proto/proto/zed.proto | 1 + crates/task/src/lib.rs | 1 - 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 55be961812a2c..93fa705f1ebd8 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4694,15 +4694,15 @@ impl Editor { value.clone(), ); } - project - .read(cx) - .task_store() - .read(cx) - .task_context_for_location( - captured_task_variables, - location, - cx, - ) + project.update(cx, |project, cx| { + project.task_store().update(cx, |task_store, cx| { + task_store.task_context_for_location( + captured_task_variables, + location, + cx, + ) + }) + }) }); Some(cx.spawn(|editor, mut cx| async move { @@ -9122,9 +9122,12 @@ impl Editor { .as_ref() .into_iter() .flat_map(|inventory| { - inventory - .read(cx) - .list_tasks(file.clone(), None, worktree_id, cx) + inventory.read(cx).list_tasks( + file.clone(), + Some(runnable.language.clone()), + worktree_id, + cx, + ) }) .filter(move |(_, template)| { template.tags.iter().any(|source_tag| source_tag == &tag) diff --git a/crates/editor/src/tasks.rs b/crates/editor/src/tasks.rs index c8d412187418d..51945a1780335 100644 --- a/crates/editor/src/tasks.rs +++ b/crates/editor/src/tasks.rs @@ -67,11 +67,11 @@ fn task_context_with_editor( variables }; - project - .read(cx) - .task_store() - .read(cx) - .task_context_for_location(captured_variables, location, cx) + project.update(cx, |project, cx| { + project.task_store().update(cx, |task_store, cx| { + task_store.task_context_for_location(captured_variables, location, cx) + }) + }) } pub fn task_context(workspace: &Workspace, cx: &mut WindowContext<'_>) -> AsyncTask { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 5098097b3dc26..28d9f056d6cf1 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -841,6 +841,7 @@ impl Project { .await } + #[allow(clippy::too_many_arguments)] async fn from_join_project_response( response: TypedEnvelope, subscriptions: [EntitySubscription; 5], diff --git a/crates/project/src/task_store.rs b/crates/project/src/task_store.rs index 32c4ff5ca7b34..3d2f255c1e1f0 100644 --- a/crates/project/src/task_store.rs +++ b/crates/project/src/task_store.rs @@ -61,6 +61,7 @@ impl TaskSettingsStore for TaskSettings { worktree: Option, templates: RawTaskTemplates<'a>, ) { + // TODO kb logging or a pop-up (separatee per kind of templates?) let mut bad_templates = 0; match worktree { @@ -169,14 +170,13 @@ impl TaskStore { .location .context("no location given for task context handling")?; let (buffer_store, is_remote) = store.update(&mut cx, |store, _| { - let (store, is_remote) = match store { + Ok(match store { TaskStore::Local { buffer_store, .. } => (buffer_store.clone(), false), TaskStore::Remote { buffer_store, .. } => (buffer_store.clone(), true), TaskStore::Empty => { anyhow::bail!("empty task store cannot handle task context requests") } - }; - Ok((store, is_remote)) + }) })??; let buffer_store = buffer_store .upgrade() @@ -216,9 +216,15 @@ impl TaskStore { range: start..end, }; let context_task = store.update(&mut cx, |store, cx| { - // TODO kb why not send the original task variables from the client? let captured_variables = { - let mut variables = TaskVariables::default(); + let mut variables = TaskVariables::from_iter( + envelope + .payload + .task_variables + .into_iter() + .filter_map(|(k, v)| Some((k.parse().log_err()?, v))), + ); + for range in location .buffer .read(cx) @@ -282,7 +288,7 @@ impl TaskStore { &self, captured_variables: TaskVariables, location: Location, - cx: &AppContext, + cx: &mut AppContext, ) -> Task> { match self { TaskStore::Local { @@ -297,8 +303,16 @@ impl TaskStore { cx, ), TaskStore::Remote { - upstream_client, .. - } => remote_task_context_for_location(upstream_client, location, cx), + upstream_client, + worktree_store, + .. + } => remote_task_context_for_location( + upstream_client, + worktree_store.clone(), + captured_variables, + location, + cx, + ), TaskStore::Empty => Task::ready(None), } } @@ -386,9 +400,18 @@ fn local_task_context_for_location( fn remote_task_context_for_location( upstream_client: &AnyProtoClient, + worktree_store: Model, + captured_variables: TaskVariables, location: Location, - cx: &AppContext, + cx: &mut AppContext, ) -> Task> { + // We need to gather a client context, as the headless one may lack certain information (e.g. tree-sitter parsing is disabled there, so symbols are not available). + let mut remote_context = BasicContextProvider::new(worktree_store) + .build_context(&TaskVariables::default(), &location, None, cx) + .log_err() + .unwrap_or_default(); + remote_context.extend(captured_variables); + let context_task = upstream_client.request(proto::TaskContextForLocation { project_id: SSH_PROJECT_ID, location: Some(proto::Location { @@ -396,6 +419,10 @@ fn remote_task_context_for_location( start: Some(serialize_anchor(&location.range.start)), end: Some(serialize_anchor(&location.range.end)), }), + task_variables: remote_context + .into_iter() + .map(|(k, v)| (k.to_string(), v)) + .collect(), }); cx.spawn(|_| async move { let task_context = context_task.await.log_err()?; diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index 84e82b3df87a9..656f3b7d19a98 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -2257,6 +2257,7 @@ message GetSupermavenApiKeyResponse { message TaskContextForLocation { uint64 project_id = 1; Location location = 2; + map task_variables = 3; } message TaskContext { diff --git a/crates/task/src/lib.rs b/crates/task/src/lib.rs index a60e0ee1a0290..1687f8f6964e6 100644 --- a/crates/task/src/lib.rs +++ b/crates/task/src/lib.rs @@ -136,7 +136,6 @@ impl VariableName { impl FromStr for VariableName { type Err = (); - // TODO kb need a derive instead fn from_str(s: &str) -> Result { let without_prefix = s.strip_prefix(ZED_VARIABLE_NAME_PREFIX).ok_or(())?; let value = match without_prefix {