From 8a97e9c57308b710d7610c0546ba798d8de70728 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 28 May 2021 13:35:21 +0200 Subject: [PATCH] Implement `select-smaller-syntax-node` for buffer --- zed/src/editor/buffer_view.rs | 55 ++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index 1026758ce7..22aa5d7476 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -171,6 +171,11 @@ pub fn init(app: &mut MutableAppContext) { "buffer:select-larger-syntax-node", Some("BufferView"), ), + Binding::new( + "alt-down", + "buffer:select-smaller-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")), @@ -279,6 +284,10 @@ pub fn init(app: &mut MutableAppContext) { "buffer:select-larger-syntax-node", BufferView::select_larger_syntax_node, ); + app.add_action( + "buffer:select-smaller-syntax-node", + BufferView::select_smaller_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); @@ -309,6 +318,7 @@ pub struct BufferView { pending_selection: Option, next_selection_id: usize, add_selections_state: Option, + select_larger_syntax_node_stack: Vec>, scroll_position: Mutex, autoscroll_requested: Mutex, settings: watch::Receiver, @@ -368,6 +378,7 @@ impl BufferView { pending_selection: None, next_selection_id, add_selections_state: None, + select_larger_syntax_node_stack: Vec::new(), scroll_position: Mutex::new(Vector2F::zero()), autoscroll_requested: Mutex::new(false), settings, @@ -1763,25 +1774,48 @@ impl BufferView { pub fn select_larger_syntax_node(&mut self, _: &(), ctx: &mut ViewContext) { 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); + + let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); + let mut selected_larger_node = false; + let old_selections = self.selections(app).to_vec(); + let mut new_selections = Vec::new(); + for selection in &old_selections { + let old_range = selection.start.to_offset(buffer)..selection.end.to_offset(buffer); + let mut new_range = old_range.clone(); while let Some(containing_range) = - buffer.range_for_containing_syntax_node(range.clone()) + buffer.range_for_containing_syntax_node(new_range.clone()) { - range = containing_range; - if !self.display_map.intersects_fold(range.start, app) - && !self.display_map.intersects_fold(range.end, app) + new_range = containing_range; + if !self.display_map.intersects_fold(new_range.start, app) + && !self.display_map.intersects_fold(new_range.end, app) { break; } } - selection.start = buffer.anchor_before(range.start); - selection.end = buffer.anchor_before(range.end); + selected_larger_node |= new_range != old_range; + new_selections.push(Selection { + id: selection.id, + start: buffer.anchor_before(new_range.start), + end: buffer.anchor_before(new_range.end), + reversed: selection.reversed, + goal: SelectionGoal::None, + }); } - self.update_selections(selections, true, ctx); + if selected_larger_node { + stack.push(old_selections); + self.update_selections(new_selections, true, ctx); + } + self.select_larger_syntax_node_stack = stack; + } + + pub fn select_smaller_syntax_node(&mut self, _: &(), ctx: &mut ViewContext) { + let mut stack = mem::take(&mut self.select_larger_syntax_node_stack); + if let Some(selections) = stack.pop() { + self.update_selections(selections, true, ctx); + } + self.select_larger_syntax_node_stack = stack; } fn build_columnar_selection( @@ -1898,6 +1932,7 @@ impl BufferView { } self.add_selections_state = None; + self.select_larger_syntax_node_stack.clear(); } fn start_transaction(&self, ctx: &mut ViewContext) {