@@ -504,7 +504,7 @@ pub struct Editor {
>,
last_bounds: Option<Bounds<Pixels>>,
expect_bounds_change: Option<Bounds<Pixels>>,
- tasks: HashMap<u32, RunnableTasks>,
+ tasks: HashMap<(BufferId, u32), (usize, RunnableTasks)>,
tasks_update_task: Option<Task<()>>,
}
@@ -3839,7 +3839,7 @@ impl Editor {
}
}
drop(context_menu);
-
+ let snapshot = self.snapshot(cx);
let deployed_from_indicator = action.deployed_from_indicator;
let mut task = self.code_actions_task.take();
let action = action.clone();
@@ -3851,11 +3851,24 @@ impl Editor {
let spawned_test_task = this.update(&mut cx, |this, cx| {
if this.focus_handle.is_focused(cx) {
- let buffer_row = action
+ let display_row = action
.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);
- let tasks = this.tasks.get(&buffer_row).map(|t| Arc::new(t.to_owned()));
- let (location, code_actions) = this
+ let (buffer, buffer_row) = snapshot
+ .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
.clone()
.and_then(|(location, code_actions)| {
@@ -3869,25 +3882,20 @@ impl Editor {
}
})
.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() {
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.discard_inline_completion(cx);
let task_context = tasks.as_ref().zip(this.workspace.clone()).and_then(
|(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 location = Location {
buffer: buffer.clone(),
@@ -3906,6 +3914,7 @@ impl Editor {
.map(|(tasks, task_context)| {
Arc::new(ResolvedTasks {
templates: tasks
+ .1
.templates
.iter()
.filter_map(|(kind, template)| {
@@ -3914,7 +3923,7 @@ impl Editor {
.map(|task| (kind.clone(), task))
})
.collect(),
- position: Point::new(buffer_row, tasks.column),
+ position: Point::new(buffer_row, tasks.1.column),
})
});
let spawn_straight_away = tasks
@@ -4505,8 +4514,8 @@ impl Editor {
self.tasks.clear()
}
- fn insert_tasks(&mut self, row: u32, tasks: RunnableTasks) {
- if let Some(_) = self.tasks.insert(row, tasks) {
+ fn insert_tasks(&mut self, key: (BufferId, u32), value: (usize, RunnableTasks)) {
+ if let Some(_) = self.tasks.insert(key, value) {
// 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")
}
@@ -7726,8 +7735,8 @@ impl Editor {
this.update(&mut cx, |this, _| {
this.clear_tasks();
- for (row, tasks) in rows {
- this.insert_tasks(row, tasks);
+ for (key, value) in rows {
+ this.insert_tasks(key, value);
}
})
.ok();
@@ -7736,19 +7745,19 @@ impl Editor {
fn fetch_runnable_ranges(
snapshot: &DisplaySnapshot,
range: Range<Anchor>,
- ) -> Vec<(Range<usize>, Runnable)> {
+ ) -> Vec<(BufferId, Range<usize>, Runnable)> {
snapshot.buffer_snapshot.runnable_ranges(range).collect()
}
fn runnable_rows(
project: Model<Project>,
snapshot: DisplaySnapshot,
- runnable_ranges: Vec<(Range<usize>, Runnable)>,
+ runnable_ranges: Vec<(BufferId, Range<usize>, Runnable)>,
mut cx: AsyncWindowContext,
- ) -> Vec<(u32, RunnableTasks)> {
+ ) -> Vec<((BufferId, u32), (usize, RunnableTasks))> {
runnable_ranges
.into_iter()
- .filter_map(|(multi_buffer_range, mut runnable)| {
+ .filter_map(|(buffer_id, multi_buffer_range, mut runnable)| {
let (tasks, _) = cx
.update(|cx| Self::resolve_runnable(project.clone(), &mut runnable, cx))
.ok()?;
@@ -7756,12 +7765,21 @@ impl Editor {
return None;
}
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((
- point.row,
- RunnableTasks {
- templates: tasks,
- column: point.column,
- },
+ (buffer_id, row),
+ (
+ multi_buffer_range.start,
+ RunnableTasks {
+ templates: tasks,
+ column: point.column,
+ },
+ ),
))
})
.collect()
@@ -10102,6 +10120,7 @@ impl Editor {
predecessor,
excerpts,
} => {
+ self.tasks_update_task = Some(self.refresh_runnables(cx));
cx.emit(EditorEvent::ExcerptsAdded {
buffer: buffer.clone(),
predecessor: *predecessor,
@@ -1406,20 +1406,24 @@ impl EditorElement {
};
editor
.tasks
- .keys()
- .filter_map(|row| {
+ .iter()
+ .filter_map(|((_, row), (multibuffer_offset, _))| {
if snapshot.is_line_folded(*row) {
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(
&self.style,
Some(*row) == active_task_indicator_row,
- *row,
+ display_row,
cx,
);
- let display_row = Point::new(*row, 0)
- .to_display_point(&snapshot.display_snapshot)
- .row();
+
let button = prepaint_gutter_button(
button,
display_row,
@@ -4035,20 +4039,25 @@ impl Element for EditorElement {
if gutter_settings.code_actions {
let newest_selection_point =
newest_selection_head.to_point(&snapshot.display_snapshot);
- let has_test_indicator = self
- .editor
- .read(cx)
- .tasks
- .contains_key(&newest_selection_point.row);
- if !has_test_indicator {
- code_actions_indicator = self.layout_code_actions_indicator(
- line_height,
- newest_selection_head,
- scroll_pixel_position,
- &gutter_dimensions,
- &gutter_hitbox,
- cx,
- );
+ let buffer = snapshot
+ .buffer_snapshot
+ .buffer_line_for_row(newest_selection_point.row);
+ if let Some((buffer, range)) = buffer {
+ let buffer_id = buffer.remote_id();
+ let row = range.start.row;
+ let has_test_indicator =
+ self.editor.read(cx).tasks.contains_key(&(buffer_id, row));
+
+ if !has_test_indicator {
+ code_actions_indicator = self.layout_code_actions_indicator(
+ line_height,
+ newest_selection_head,
+ scroll_pixel_position,
+ &gutter_dimensions,
+ &gutter_hitbox,
+ cx,
+ );
+ }
}
}
}
@@ -3168,7 +3168,7 @@ impl MultiBufferSnapshot {
pub fn runnable_ranges(
&self,
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);
self.excerpts_for_range(range.clone())
.flat_map(move |(excerpt, excerpt_offset)| {
@@ -3183,10 +3183,10 @@ impl MultiBufferSnapshot {
excerpt_offset + (match_range.start - 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)
- .take_while(move |(match_range, _)| match_range.start < range.end)
+ .skip_while(move |(_, match_range, _)| match_range.end < range.start)
+ .take_while(move |(_, match_range, _)| match_range.start < range.end)
})
}