Improve LSP tasks ergonomics (#31551)

* stopped fetching LSP tasks for too long (but still use the hardcoded
value for the time being — the LSP tasks settings part is a simple bool
key and it's not very simple to fit in another value there)

* introduced `prefer_lsp` language task settings value, to control
whether in the gutter/modal/both/none LSP tasks are shown exclusively,
if possible

Release Notes:

- Added a way to prefer LSP tasks over Zed tasks
This commit is contained in:
Kirill Bulatov 2025-05-28 18:36:25 +03:00 committed by GitHub
parent 00bc154c46
commit 07403f0b08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 128 additions and 44 deletions

View file

@ -1,6 +1,7 @@
use std::sync::Arc;
use crate::TaskContexts;
use editor::Editor;
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
Action, AnyElement, App, AppContext as _, Context, DismissEvent, Entity, EventEmitter,
@ -230,15 +231,28 @@ impl PickerDelegate for TasksModalDelegate {
let workspace = self.workspace.clone();
let lsp_task_sources = self.task_contexts.lsp_task_sources.clone();
let task_position = self.task_contexts.latest_selection;
cx.spawn(async move |picker, cx| {
let Ok(lsp_tasks) = workspace.update(cx, |workspace, cx| {
editor::lsp_tasks(
let Ok((lsp_tasks, prefer_lsp)) = workspace.update(cx, |workspace, cx| {
let lsp_tasks = editor::lsp_tasks(
workspace.project().clone(),
&lsp_task_sources,
task_position,
cx,
)
);
let prefer_lsp = workspace
.active_item(cx)
.and_then(|item| item.downcast::<Editor>())
.map(|editor| {
editor
.read(cx)
.buffer()
.read(cx)
.language_settings(cx)
.tasks
.prefer_lsp
})
.unwrap_or(false);
(lsp_tasks, prefer_lsp)
}) else {
return Vec::new();
};
@ -253,6 +267,8 @@ impl PickerDelegate for TasksModalDelegate {
};
let mut new_candidates = used;
let add_current_language_tasks =
!prefer_lsp || lsp_tasks.is_empty();
new_candidates.extend(lsp_tasks.into_iter().flat_map(
|(kind, tasks_with_locations)| {
tasks_with_locations
@ -263,7 +279,12 @@ impl PickerDelegate for TasksModalDelegate {
.map(move |(_, task)| (kind.clone(), task))
},
));
new_candidates.extend(current);
new_candidates.extend(current.into_iter().filter(
|(task_kind, _)| {
add_current_language_tasks
|| !matches!(task_kind, TaskSourceKind::Language { .. })
},
));
let match_candidates = string_match_candidates(&new_candidates);
let _ = picker.delegate.candidates.insert(new_candidates);
match_candidates