tasks: Reorganize task modal (#11752)

![image](https://github.com/zed-industries/zed/assets/24362066/bc7cc3d3-d9fc-4be6-b9b6-e3d8edf5b533)

Release Notes:
- Improved tasks modal by highlighting a distinction between a task
template and concrete task instance and surfacing available keybindings
more prominently. Task templates are now always available in the modal,
even if there's already a history entry with the same label.
- Changed default key binding for "picker::UseSelectedQuery" to `opt-e`.
This commit is contained in:
Piotr Osiewicz 2024-05-14 11:22:09 +02:00 committed by GitHub
parent 0a096bf531
commit 95e0d5ed74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 160 additions and 47 deletions

View file

@ -8,7 +8,7 @@ use std::{
use collections::{btree_map, BTreeMap, VecDeque};
use gpui::{AppContext, Context, Model, ModelContext};
use itertools::{Either, Itertools};
use itertools::Itertools;
use language::Language;
use task::{
static_source::StaticSource, ResolvedTask, TaskContext, TaskId, TaskTemplate, VariableName,
@ -188,7 +188,6 @@ impl Inventory {
.last_scheduled_tasks
.iter()
.rev()
.filter(|(_, task)| !task.original_task().ignore_previously_resolved)
.filter(|(task_kind, _)| {
if matches!(task_kind, TaskSourceKind::Language { .. }) {
Some(task_kind) == task_source_kind.as_ref()
@ -256,38 +255,46 @@ impl Inventory {
tasks_by_label
},
);
tasks_by_label = currently_resolved_tasks.into_iter().fold(
tasks_by_label = currently_resolved_tasks.iter().fold(
tasks_by_label,
|mut tasks_by_label, (source, task, lru_score)| {
match tasks_by_label.entry((source, task.resolved_label.clone())) {
match tasks_by_label.entry((source.clone(), task.resolved_label.clone())) {
btree_map::Entry::Occupied(mut o) => {
let (previous_task, _) = o.get();
let new_template = task.original_task();
if new_template.ignore_previously_resolved
|| new_template != previous_task.original_task()
{
o.insert((task, lru_score));
if new_template != previous_task.original_task() {
o.insert((task.clone(), *lru_score));
}
}
btree_map::Entry::Vacant(v) => {
v.insert((task, lru_score));
v.insert((task.clone(), *lru_score));
}
}
tasks_by_label
},
);
tasks_by_label
let resolved = tasks_by_label
.into_iter()
.map(|((kind, _), (task, lru_score))| (kind, task, lru_score))
.sorted_unstable_by(task_lru_comparator)
.partition_map(|(kind, task, lru_score)| {
.sorted_by(task_lru_comparator)
.filter_map(|(kind, task, lru_score)| {
if lru_score < not_used_score {
Either::Left((kind, task))
Some((kind, task))
} else {
Either::Right((kind, task))
None
}
})
.collect();
(
resolved,
currently_resolved_tasks
.into_iter()
.sorted_unstable_by(task_lru_comparator)
.map(|(kind, task, _)| (kind, task))
.collect(),
)
}
/// Returns the last scheduled task, if any of the sources contains one with the matching id.
@ -334,6 +341,7 @@ fn task_lru_comparator(
&task_b.resolved_label,
))
.then(task_a.resolved_label.cmp(&task_b.resolved_label))
.then(kind_a.cmp(kind_b))
})
}
@ -530,6 +538,7 @@ mod tests {
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"2_task".to_string(),
"2_task".to_string(),
"1_a_task".to_string(),
"1_task".to_string(),
@ -548,6 +557,9 @@ mod tests {
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
@ -578,6 +590,9 @@ mod tests {
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
@ -595,6 +610,10 @@ mod tests {
assert_eq!(
resolved_task_names(&inventory, None, cx),
vec![
"11_hello".to_string(),
"3_task".to_string(),
"1_task".to_string(),
"2_task".to_string(),
"11_hello".to_string(),
"3_task".to_string(),
"1_task".to_string(),