Task indicators in multibuffers (#11603)

Following #11487 the task indicators would no longer show up in
multibuffers.
Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2024-05-09 12:22:33 +02:00 committed by GitHub
parent fdcedf15b7
commit 76535578e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 83 additions and 60 deletions

View file

@ -52,16 +52,11 @@ pub struct SelectToEndOfLine {
#[derive(PartialEq, Clone, Deserialize, Default)] #[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ToggleCodeActions { pub struct ToggleCodeActions {
// Display row from which the action was deployed.
#[serde(default)] #[serde(default)]
pub deployed_from_indicator: Option<u32>, pub deployed_from_indicator: Option<u32>,
} }
#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ToggleTestRunner {
#[serde(default)]
pub deployed_from_row: Option<u32>,
}
#[derive(PartialEq, Clone, Deserialize, Default)] #[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ConfirmCompletion { pub struct ConfirmCompletion {
#[serde(default)] #[serde(default)]

View file

@ -504,7 +504,7 @@ pub struct Editor {
>, >,
last_bounds: Option<Bounds<Pixels>>, last_bounds: Option<Bounds<Pixels>>,
expect_bounds_change: Option<Bounds<Pixels>>, expect_bounds_change: Option<Bounds<Pixels>>,
tasks: HashMap<u32, RunnableTasks>, tasks: HashMap<(BufferId, u32), (usize, RunnableTasks)>,
tasks_update_task: Option<Task<()>>, tasks_update_task: Option<Task<()>>,
} }
@ -3839,7 +3839,7 @@ impl Editor {
} }
} }
drop(context_menu); drop(context_menu);
let snapshot = self.snapshot(cx);
let deployed_from_indicator = action.deployed_from_indicator; let deployed_from_indicator = action.deployed_from_indicator;
let mut task = self.code_actions_task.take(); let mut task = self.code_actions_task.take();
let action = action.clone(); let action = action.clone();
@ -3851,11 +3851,24 @@ impl Editor {
let spawned_test_task = this.update(&mut cx, |this, cx| { let spawned_test_task = this.update(&mut cx, |this, cx| {
if this.focus_handle.is_focused(cx) { if this.focus_handle.is_focused(cx) {
let buffer_row = action let display_row = action
.deployed_from_indicator .deployed_from_indicator
.map(|row| {
DisplayPoint::new(row, 0)
.to_point(&snapshot.display_snapshot)
.row
})
.unwrap_or_else(|| this.selections.newest::<Point>(cx).head().row); .unwrap_or_else(|| this.selections.newest::<Point>(cx).head().row);
let tasks = this.tasks.get(&buffer_row).map(|t| Arc::new(t.to_owned())); let (buffer, buffer_row) = snapshot
let (location, code_actions) = this .buffer_snapshot
.buffer_line_for_row(display_row)
.and_then(|(buffer_snapshot, range)| {
this.buffer
.read(cx)
.buffer(buffer_snapshot.remote_id())
.map(|buffer| (buffer, range.start.row))
})?;
let (_, code_actions) = this
.available_code_actions .available_code_actions
.clone() .clone()
.and_then(|(location, code_actions)| { .and_then(|(location, code_actions)| {
@ -3869,25 +3882,20 @@ impl Editor {
} }
}) })
.unzip(); .unzip();
let buffer_id = buffer.read(cx).remote_id();
let tasks = this
.tasks
.get(&(buffer_id, buffer_row))
.map(|t| Arc::new(t.to_owned()));
if tasks.is_none() && code_actions.is_none() { if tasks.is_none() && code_actions.is_none() {
return None; return None;
} }
let buffer = location.map(|location| location.buffer).or_else(|| {
let snapshot = this.snapshot(cx);
let (buffer_snapshot, _) =
snapshot.buffer_snapshot.buffer_line_for_row(buffer_row)?;
let buffer_id = buffer_snapshot.remote_id();
this.buffer().read(cx).buffer(buffer_id)
});
let Some(buffer) = buffer else {
return None;
};
this.completion_tasks.clear(); this.completion_tasks.clear();
this.discard_inline_completion(cx); this.discard_inline_completion(cx);
let task_context = tasks.as_ref().zip(this.workspace.clone()).and_then( let task_context = tasks.as_ref().zip(this.workspace.clone()).and_then(
|(tasks, (workspace, _))| { |(tasks, (workspace, _))| {
let position = Point::new(buffer_row, tasks.column); let position = Point::new(buffer_row, tasks.1.column);
let range_start = buffer.read(cx).anchor_at(position, Bias::Right); let range_start = buffer.read(cx).anchor_at(position, Bias::Right);
let location = Location { let location = Location {
buffer: buffer.clone(), buffer: buffer.clone(),
@ -3906,6 +3914,7 @@ impl Editor {
.map(|(tasks, task_context)| { .map(|(tasks, task_context)| {
Arc::new(ResolvedTasks { Arc::new(ResolvedTasks {
templates: tasks templates: tasks
.1
.templates .templates
.iter() .iter()
.filter_map(|(kind, template)| { .filter_map(|(kind, template)| {
@ -3914,7 +3923,7 @@ impl Editor {
.map(|task| (kind.clone(), task)) .map(|task| (kind.clone(), task))
}) })
.collect(), .collect(),
position: Point::new(buffer_row, tasks.column), position: Point::new(buffer_row, tasks.1.column),
}) })
}); });
let spawn_straight_away = tasks let spawn_straight_away = tasks
@ -4505,8 +4514,8 @@ impl Editor {
self.tasks.clear() self.tasks.clear()
} }
fn insert_tasks(&mut self, row: u32, tasks: RunnableTasks) { fn insert_tasks(&mut self, key: (BufferId, u32), value: (usize, RunnableTasks)) {
if let Some(_) = self.tasks.insert(row, tasks) { if let Some(_) = self.tasks.insert(key, value) {
// This case should hopefully be rare, but just in case... // This case should hopefully be rare, but just in case...
log::error!("multiple different run targets found on a single line, only the last target will be rendered") log::error!("multiple different run targets found on a single line, only the last target will be rendered")
} }
@ -7726,8 +7735,8 @@ impl Editor {
this.update(&mut cx, |this, _| { this.update(&mut cx, |this, _| {
this.clear_tasks(); this.clear_tasks();
for (row, tasks) in rows { for (key, value) in rows {
this.insert_tasks(row, tasks); this.insert_tasks(key, value);
} }
}) })
.ok(); .ok();
@ -7736,19 +7745,19 @@ impl Editor {
fn fetch_runnable_ranges( fn fetch_runnable_ranges(
snapshot: &DisplaySnapshot, snapshot: &DisplaySnapshot,
range: Range<Anchor>, range: Range<Anchor>,
) -> Vec<(Range<usize>, Runnable)> { ) -> Vec<(BufferId, Range<usize>, Runnable)> {
snapshot.buffer_snapshot.runnable_ranges(range).collect() snapshot.buffer_snapshot.runnable_ranges(range).collect()
} }
fn runnable_rows( fn runnable_rows(
project: Model<Project>, project: Model<Project>,
snapshot: DisplaySnapshot, snapshot: DisplaySnapshot,
runnable_ranges: Vec<(Range<usize>, Runnable)>, runnable_ranges: Vec<(BufferId, Range<usize>, Runnable)>,
mut cx: AsyncWindowContext, mut cx: AsyncWindowContext,
) -> Vec<(u32, RunnableTasks)> { ) -> Vec<((BufferId, u32), (usize, RunnableTasks))> {
runnable_ranges runnable_ranges
.into_iter() .into_iter()
.filter_map(|(multi_buffer_range, mut runnable)| { .filter_map(|(buffer_id, multi_buffer_range, mut runnable)| {
let (tasks, _) = cx let (tasks, _) = cx
.update(|cx| Self::resolve_runnable(project.clone(), &mut runnable, cx)) .update(|cx| Self::resolve_runnable(project.clone(), &mut runnable, cx))
.ok()?; .ok()?;
@ -7756,12 +7765,21 @@ impl Editor {
return None; return None;
} }
let point = multi_buffer_range.start.to_point(&snapshot.buffer_snapshot); let point = multi_buffer_range.start.to_point(&snapshot.buffer_snapshot);
let row = snapshot
.buffer_snapshot
.buffer_line_for_row(point.row)?
.1
.start
.row;
Some(( Some((
point.row, (buffer_id, row),
RunnableTasks { (
templates: tasks, multi_buffer_range.start,
column: point.column, RunnableTasks {
}, templates: tasks,
column: point.column,
},
),
)) ))
}) })
.collect() .collect()
@ -10102,6 +10120,7 @@ impl Editor {
predecessor, predecessor,
excerpts, excerpts,
} => { } => {
self.tasks_update_task = Some(self.refresh_runnables(cx));
cx.emit(EditorEvent::ExcerptsAdded { cx.emit(EditorEvent::ExcerptsAdded {
buffer: buffer.clone(), buffer: buffer.clone(),
predecessor: *predecessor, predecessor: *predecessor,

View file

@ -1406,20 +1406,24 @@ impl EditorElement {
}; };
editor editor
.tasks .tasks
.keys() .iter()
.filter_map(|row| { .filter_map(|((_, row), (multibuffer_offset, _))| {
if snapshot.is_line_folded(*row) { if snapshot.is_line_folded(*row) {
return None; return None;
} }
let display_row = snapshot
.buffer_snapshot
.offset_to_point(*multibuffer_offset)
.to_display_point(&snapshot.display_snapshot)
.row();
let button = editor.render_run_indicator( let button = editor.render_run_indicator(
&self.style, &self.style,
Some(*row) == active_task_indicator_row, Some(*row) == active_task_indicator_row,
*row, display_row,
cx, cx,
); );
let display_row = Point::new(*row, 0)
.to_display_point(&snapshot.display_snapshot)
.row();
let button = prepaint_gutter_button( let button = prepaint_gutter_button(
button, button,
display_row, display_row,
@ -4035,20 +4039,25 @@ impl Element for EditorElement {
if gutter_settings.code_actions { if gutter_settings.code_actions {
let newest_selection_point = let newest_selection_point =
newest_selection_head.to_point(&snapshot.display_snapshot); newest_selection_head.to_point(&snapshot.display_snapshot);
let has_test_indicator = self let buffer = snapshot
.editor .buffer_snapshot
.read(cx) .buffer_line_for_row(newest_selection_point.row);
.tasks if let Some((buffer, range)) = buffer {
.contains_key(&newest_selection_point.row); let buffer_id = buffer.remote_id();
if !has_test_indicator { let row = range.start.row;
code_actions_indicator = self.layout_code_actions_indicator( let has_test_indicator =
line_height, self.editor.read(cx).tasks.contains_key(&(buffer_id, row));
newest_selection_head,
scroll_pixel_position, if !has_test_indicator {
&gutter_dimensions, code_actions_indicator = self.layout_code_actions_indicator(
&gutter_hitbox, line_height,
cx, newest_selection_head,
); scroll_pixel_position,
&gutter_dimensions,
&gutter_hitbox,
cx,
);
}
} }
} }
} }

View file

@ -3168,7 +3168,7 @@ impl MultiBufferSnapshot {
pub fn runnable_ranges( pub fn runnable_ranges(
&self, &self,
range: Range<Anchor>, range: Range<Anchor>,
) -> impl Iterator<Item = (Range<usize>, Runnable)> + '_ { ) -> impl Iterator<Item = (BufferId, Range<usize>, Runnable)> + '_ {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
self.excerpts_for_range(range.clone()) self.excerpts_for_range(range.clone())
.flat_map(move |(excerpt, excerpt_offset)| { .flat_map(move |(excerpt, excerpt_offset)| {
@ -3183,10 +3183,10 @@ impl MultiBufferSnapshot {
excerpt_offset + (match_range.start - excerpt_buffer_start); excerpt_offset + (match_range.start - excerpt_buffer_start);
match_range.end = excerpt_offset + (match_range.end - excerpt_buffer_start); match_range.end = excerpt_offset + (match_range.end - excerpt_buffer_start);
(match_range, runnable) (excerpt.buffer_id, match_range, runnable)
}) })
.skip_while(move |(match_range, _)| match_range.end < range.start) .skip_while(move |(_, match_range, _)| match_range.end < range.start)
.take_while(move |(match_range, _)| match_range.start < range.end) .take_while(move |(_, match_range, _)| match_range.start < range.end)
}) })
} }