mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-14 22:14:23 +00:00
Implement select_larger_syntax_node
for buffer
This commit is contained in:
parent
6992c19aee
commit
23d1d91414
4 changed files with 67 additions and 1 deletions
|
@ -709,6 +709,23 @@ impl Buffer {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn range_for_containing_syntax_node<T: ToOffset>(
|
||||
&self,
|
||||
range: Range<T>,
|
||||
) -> Option<Range<usize>> {
|
||||
if let Some(tree) = self.syntax_tree() {
|
||||
let root = tree.root_node();
|
||||
let range = range.start.to_offset(self)..range.end.to_offset(self);
|
||||
let mut node = root.descendant_for_byte_range(range.start, range.end);
|
||||
while node.map_or(false, |n| n.byte_range() == range) {
|
||||
node = node.unwrap().parent();
|
||||
}
|
||||
node.map(|n| n.byte_range())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn diff(&self, new_text: Arc<str>, ctx: &AppContext) -> Task<Diff> {
|
||||
// TODO: it would be nice to not allocate here.
|
||||
let old_text = self.text();
|
||||
|
|
|
@ -166,6 +166,11 @@ pub fn init(app: &mut MutableAppContext) {
|
|||
"buffer:add_selection_below",
|
||||
Some("BufferView"),
|
||||
),
|
||||
Binding::new(
|
||||
"alt-up",
|
||||
"buffer:select-larger-syntax-node",
|
||||
Some("BufferView"),
|
||||
),
|
||||
Binding::new("pageup", "buffer:page_up", Some("BufferView")),
|
||||
Binding::new("pagedown", "buffer:page_down", Some("BufferView")),
|
||||
Binding::new("alt-cmd-[", "buffer:fold", Some("BufferView")),
|
||||
|
@ -270,6 +275,10 @@ pub fn init(app: &mut MutableAppContext) {
|
|||
"buffer:add_selection_below",
|
||||
BufferView::add_selection_below,
|
||||
);
|
||||
app.add_action(
|
||||
"buffer:select-larger-syntax-node",
|
||||
BufferView::select_larger_syntax_node,
|
||||
);
|
||||
app.add_action("buffer:page_up", BufferView::page_up);
|
||||
app.add_action("buffer:page_down", BufferView::page_down);
|
||||
app.add_action("buffer:fold", BufferView::fold);
|
||||
|
@ -1659,7 +1668,7 @@ impl BufferView {
|
|||
self.add_selection(false, ctx);
|
||||
}
|
||||
|
||||
pub fn add_selection(&mut self, above: bool, ctx: &mut ViewContext<Self>) {
|
||||
fn add_selection(&mut self, above: bool, ctx: &mut ViewContext<Self>) {
|
||||
use super::RangeExt;
|
||||
|
||||
let app = ctx.as_ref();
|
||||
|
@ -1751,6 +1760,30 @@ impl BufferView {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn select_larger_syntax_node(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
|
||||
let app = ctx.as_ref();
|
||||
let buffer = self.buffer.read(app);
|
||||
let mut selections = self.selections(app).to_vec();
|
||||
for selection in &mut selections {
|
||||
let mut range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer);
|
||||
while let Some(containing_range) =
|
||||
buffer.range_for_containing_syntax_node(range.clone())
|
||||
{
|
||||
range = containing_range;
|
||||
if !self.display_map.intersects_fold(range.start, app)
|
||||
&& !self.display_map.intersects_fold(range.end, app)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selection.start = buffer.anchor_before(range.start);
|
||||
selection.end = buffer.anchor_before(range.end);
|
||||
}
|
||||
|
||||
self.update_selections(selections, true, ctx);
|
||||
}
|
||||
|
||||
fn build_columnar_selection(
|
||||
&mut self,
|
||||
row: u32,
|
||||
|
|
|
@ -192,6 +192,18 @@ impl FoldMap {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn intersects_fold<T>(&self, offset: T, ctx: &AppContext) -> bool
|
||||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
let buffer = self.buffer.read(ctx);
|
||||
let offset = offset.to_offset(buffer);
|
||||
let transforms = self.sync(ctx);
|
||||
let mut cursor = transforms.cursor::<usize, usize>();
|
||||
cursor.seek(&offset, SeekBias::Right, &());
|
||||
cursor.item().map_or(false, |t| t.display_text.is_some())
|
||||
}
|
||||
|
||||
pub fn is_line_folded(&self, display_row: u32, ctx: &AppContext) -> bool {
|
||||
let transforms = self.sync(ctx);
|
||||
let mut cursor = transforms.cursor::<DisplayPoint, DisplayPoint>();
|
||||
|
|
|
@ -57,6 +57,10 @@ impl DisplayMap {
|
|||
self.fold_map.unfold(ranges, ctx)
|
||||
}
|
||||
|
||||
pub fn intersects_fold<T: ToOffset>(&self, offset: T, ctx: &AppContext) -> bool {
|
||||
self.fold_map.intersects_fold(offset, ctx)
|
||||
}
|
||||
|
||||
pub fn is_line_folded(&self, display_row: u32, ctx: &AppContext) -> bool {
|
||||
self.fold_map.is_line_folded(display_row, ctx)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue