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

@ -1670,6 +1670,13 @@ impl Editor {
editor
.refresh_inlay_hints(InlayHintRefreshReason::RefreshRequested, cx);
}
project::Event::LanguageServerAdded(..)
| project::Event::LanguageServerRemoved(..) => {
if editor.tasks_update_task.is_none() {
editor.tasks_update_task =
Some(editor.refresh_runnables(window, cx));
}
}
project::Event::SnippetEdit(id, snippet_edits) => {
if let Some(buffer) = editor.buffer.read(cx).buffer(*id) {
let focus_handle = editor.focus_handle(cx);
@ -13543,6 +13550,7 @@ impl Editor {
}
let project = self.project.as_ref().map(Entity::downgrade);
let task_sources = self.lsp_task_sources(cx);
let multi_buffer = self.buffer.downgrade();
cx.spawn_in(window, async move |editor, cx| {
cx.background_executor().timer(UPDATE_DEBOUNCE).await;
let Some(project) = project.and_then(|p| p.upgrade()) else {
@ -13626,7 +13634,19 @@ impl Editor {
return;
};
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
let Ok(prefer_lsp) = multi_buffer.update(cx, |buffer, cx| {
buffer.language_settings(cx).tasks.prefer_lsp
}) else {
return;
};
let rows = Self::runnable_rows(
project,
display_snapshot,
prefer_lsp && !lsp_tasks_by_rows.is_empty(),
new_rows,
cx.clone(),
);
editor
.update(cx, |editor, _| {
editor.clear_tasks();
@ -13654,15 +13674,21 @@ impl Editor {
fn runnable_rows(
project: Entity<Project>,
snapshot: DisplaySnapshot,
prefer_lsp: bool,
runnable_ranges: Vec<RunnableRange>,
mut cx: AsyncWindowContext,
) -> Vec<((BufferId, BufferRow), RunnableTasks)> {
runnable_ranges
.into_iter()
.filter_map(|mut runnable| {
let tasks = cx
let mut tasks = cx
.update(|_, cx| Self::templates_with_tags(&project, &mut runnable.runnable, cx))
.ok()?;
if prefer_lsp {
tasks.retain(|(task_kind, _)| {
!matches!(task_kind, TaskSourceKind::Language { .. })
});
}
if tasks.is_empty() {
return None;
}