From 5e16adc6c9f57650b77f0bdfa66dccd0ff1a101f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 22 Apr 2022 15:43:57 +0200 Subject: [PATCH] Use document highlights to prepare rename if LSP doesn't support it --- crates/editor/src/editor.rs | 55 ++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 97be28ebd420163a96a100073fd1a1a46c8e0df1..b1664dee6d6581c713a813bb6e38208c7b87a7b7 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4628,7 +4628,23 @@ impl Editor { }); Some(cx.spawn(|this, mut cx| async move { - if let Some(rename_range) = prepare_rename.await? { + let rename_range = if let Some(range) = prepare_rename.await? { + Some(range) + } else { + this.read_with(&cx, |this, cx| { + let buffer = this.buffer.read(cx).snapshot(cx); + let mut buffer_highlights = this + .document_highlights_for_position(selection.head(), &buffer) + .filter(|highlight| { + highlight.start.excerpt_id() == selection.head().excerpt_id() + && highlight.end.excerpt_id() == selection.head().excerpt_id() + }); + buffer_highlights + .next() + .map(|highlight| highlight.start.text_anchor..highlight.end.text_anchor) + }) + }; + if let Some(rename_range) = rename_range { let rename_buffer_range = rename_range.to_offset(&snapshot); let cursor_offset_in_rename_range = cursor_buffer_offset.saturating_sub(rename_buffer_range.start); @@ -5673,6 +5689,43 @@ impl Editor { self.background_highlights_in_range(start..end, &snapshot, theme) } + fn document_highlights_for_position<'a>( + &'a self, + position: Anchor, + buffer: &'a MultiBufferSnapshot, + ) -> impl 'a + Iterator> { + let read_highlights = self + .background_highlights + .get(&TypeId::of::()) + .map(|h| &h.1); + let write_highlights = self + .background_highlights + .get(&TypeId::of::()) + .map(|h| &h.1); + let left_position = position.bias_left(buffer); + let right_position = position.bias_right(buffer); + read_highlights + .into_iter() + .chain(write_highlights) + .flat_map(move |ranges| { + let start_ix = match ranges.binary_search_by(|probe| { + let cmp = probe.end.cmp(&left_position, &buffer); + if cmp.is_ge() { + Ordering::Greater + } else { + Ordering::Less + } + }) { + Ok(i) | Err(i) => i, + }; + + let right_position = right_position.clone(); + ranges[start_ix..] + .iter() + .take_while(move |range| range.start.cmp(&right_position, &buffer).is_le()) + }) + } + pub fn background_highlights_in_range( &self, search_range: Range,