Keep selections at the top of the project diagnostics view when it is first populated
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
9bbe67f0ea
commit
b19d92e918
2 changed files with 60 additions and 41 deletions
|
@ -9,7 +9,7 @@ use gpui::{
|
||||||
action, elements::*, keymap::Binding, AppContext, Entity, ModelHandle, MutableAppContext,
|
action, elements::*, keymap::Binding, AppContext, Entity, ModelHandle, MutableAppContext,
|
||||||
RenderContext, Task, View, ViewContext, ViewHandle,
|
RenderContext, Task, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use language::{Bias, Buffer, Diagnostic, DiagnosticEntry, Point};
|
use language::{Bias, Buffer, Diagnostic, DiagnosticEntry, Point, Selection, SelectionGoal};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::{Project, ProjectPath, WorktreeId};
|
use project::{Project, ProjectPath, WorktreeId};
|
||||||
use std::{cmp::Ordering, ops::Range, path::Path, sync::Arc};
|
use std::{cmp::Ordering, ops::Range, path::Path, sync::Arc};
|
||||||
|
@ -183,6 +183,7 @@ impl ProjectDiagnosticsEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let was_empty = self.path_states.is_empty();
|
||||||
let path_ix = match self
|
let path_ix = match self
|
||||||
.path_states
|
.path_states
|
||||||
.binary_search_by_key(&path.as_ref(), |e| e.0.as_ref())
|
.binary_search_by_key(&path.as_ref(), |e| e.0.as_ref())
|
||||||
|
@ -375,7 +376,21 @@ impl ProjectDiagnosticsEditor {
|
||||||
group_state.blocks = block_ids.by_ref().take(group_state.block_count).collect();
|
group_state.blocks = block_ids.by_ref().take(group_state.block_count).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if was_empty {
|
||||||
|
editor.update_selections(
|
||||||
|
vec![Selection {
|
||||||
|
id: 0,
|
||||||
|
start: 0,
|
||||||
|
end: 0,
|
||||||
|
reversed: false,
|
||||||
|
goal: SelectionGoal::None,
|
||||||
|
}],
|
||||||
|
None,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
editor.refresh_selections(cx);
|
editor.refresh_selections(cx);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for ix in group_ixs_to_remove.into_iter().rev() {
|
for ix in group_ixs_to_remove.into_iter().rev() {
|
||||||
|
@ -681,6 +696,10 @@ mod tests {
|
||||||
"}"
|
"}"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
view.editor.update(cx, |editor, cx| {
|
||||||
|
assert_eq!(editor.selected_ranges::<usize>(cx), [0..0]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
worktree.update(&mut cx, |worktree, cx| {
|
worktree.update(&mut cx, |worktree, cx| {
|
||||||
|
|
|
@ -1056,6 +1056,45 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn selected_ranges<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
|
&self,
|
||||||
|
cx: &mut MutableAppContext,
|
||||||
|
) -> Vec<Range<D>> {
|
||||||
|
self.local_selections::<D>(cx)
|
||||||
|
.iter()
|
||||||
|
.map(|s| {
|
||||||
|
if s.reversed {
|
||||||
|
s.end.clone()..s.start.clone()
|
||||||
|
} else {
|
||||||
|
s.start.clone()..s.end.clone()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn selected_display_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
|
||||||
|
let display_map = self
|
||||||
|
.display_map
|
||||||
|
.update(cx, |display_map, cx| display_map.snapshot(cx));
|
||||||
|
self.selections
|
||||||
|
.iter()
|
||||||
|
.chain(
|
||||||
|
self.pending_selection
|
||||||
|
.as_ref()
|
||||||
|
.map(|pending| &pending.selection),
|
||||||
|
)
|
||||||
|
.map(|s| {
|
||||||
|
if s.reversed {
|
||||||
|
s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
|
||||||
|
} else {
|
||||||
|
s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select_ranges<I, T>(
|
pub fn select_ranges<I, T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges: I,
|
ranges: I,
|
||||||
|
@ -6179,45 +6218,6 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Editor {
|
|
||||||
fn selected_ranges<D: TextDimension + Ord + Sub<D, Output = D>>(
|
|
||||||
&self,
|
|
||||||
cx: &mut MutableAppContext,
|
|
||||||
) -> Vec<Range<D>> {
|
|
||||||
self.local_selections::<D>(cx)
|
|
||||||
.iter()
|
|
||||||
.map(|s| {
|
|
||||||
if s.reversed {
|
|
||||||
s.end.clone()..s.start.clone()
|
|
||||||
} else {
|
|
||||||
s.start.clone()..s.end.clone()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn selected_display_ranges(&self, cx: &mut MutableAppContext) -> Vec<Range<DisplayPoint>> {
|
|
||||||
let display_map = self
|
|
||||||
.display_map
|
|
||||||
.update(cx, |display_map, cx| display_map.snapshot(cx));
|
|
||||||
self.selections
|
|
||||||
.iter()
|
|
||||||
.chain(
|
|
||||||
self.pending_selection
|
|
||||||
.as_ref()
|
|
||||||
.map(|pending| &pending.selection),
|
|
||||||
)
|
|
||||||
.map(|s| {
|
|
||||||
if s.reversed {
|
|
||||||
s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
|
|
||||||
} else {
|
|
||||||
s.start.to_display_point(&display_map)..s.end.to_display_point(&display_map)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||||
let point = DisplayPoint::new(row as u32, column as u32);
|
let point = DisplayPoint::new(row as u32, column as u32);
|
||||||
point..point
|
point..point
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue