Merge pull request #887 from zed-industries/fix-typescript-rename
Use document highlights to prepare rename if LSP doesn't support it
This commit is contained in:
commit
53bf7b61c0
5 changed files with 86 additions and 3 deletions
|
@ -3829,7 +3829,16 @@ mod tests {
|
||||||
},
|
},
|
||||||
Some(tree_sitter_rust::language()),
|
Some(tree_sitter_rust::language()),
|
||||||
);
|
);
|
||||||
let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default());
|
let mut fake_language_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
|
||||||
|
capabilities: lsp::ServerCapabilities {
|
||||||
|
rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions {
|
||||||
|
prepare_provider: Some(true),
|
||||||
|
work_done_progress_options: Default::default(),
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
lang_registry.add(Arc::new(language));
|
lang_registry.add(Arc::new(language));
|
||||||
|
|
||||||
// Connect to a server as 2 clients.
|
// Connect to a server as 2 clients.
|
||||||
|
|
|
@ -4632,7 +4632,23 @@ impl Editor {
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(cx.spawn(|this, mut cx| async move {
|
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 rename_buffer_range = rename_range.to_offset(&snapshot);
|
||||||
let cursor_offset_in_rename_range =
|
let cursor_offset_in_rename_range =
|
||||||
cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
|
cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
|
||||||
|
@ -5677,6 +5693,43 @@ impl Editor {
|
||||||
self.background_highlights_in_range(start..end, &snapshot, theme)
|
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<Item = &Range<Anchor>> {
|
||||||
|
let read_highlights = self
|
||||||
|
.background_highlights
|
||||||
|
.get(&TypeId::of::<DocumentHighlightRead>())
|
||||||
|
.map(|h| &h.1);
|
||||||
|
let write_highlights = self
|
||||||
|
.background_highlights
|
||||||
|
.get(&TypeId::of::<DocumentHighlightRead>())
|
||||||
|
.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(
|
pub fn background_highlights_in_range(
|
||||||
&self,
|
&self,
|
||||||
search_range: Range<Anchor>,
|
search_range: Range<Anchor>,
|
||||||
|
|
|
@ -292,6 +292,10 @@ impl LanguageServer {
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
rename: Some(RenameClientCapabilities {
|
||||||
|
prepare_support: Some(true),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
experimental: Some(json!({
|
experimental: Some(json!({
|
||||||
|
|
|
@ -86,6 +86,14 @@ impl LspCommand for PrepareRename {
|
||||||
type LspRequest = lsp::request::PrepareRenameRequest;
|
type LspRequest = lsp::request::PrepareRenameRequest;
|
||||||
type ProtoRequest = proto::PrepareRename;
|
type ProtoRequest = proto::PrepareRename;
|
||||||
|
|
||||||
|
fn check_capabilities(&self, capabilities: &ServerCapabilities) -> bool {
|
||||||
|
if let Some(lsp::OneOf::Right(rename)) = &capabilities.rename_provider {
|
||||||
|
rename.prepare_provider == Some(true)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_lsp(&self, path: &Path, _: &AppContext) -> lsp::TextDocumentPositionParams {
|
fn to_lsp(&self, path: &Path, _: &AppContext) -> lsp::TextDocumentPositionParams {
|
||||||
lsp::TextDocumentPositionParams {
|
lsp::TextDocumentPositionParams {
|
||||||
text_document: lsp::TextDocumentIdentifier {
|
text_document: lsp::TextDocumentIdentifier {
|
||||||
|
|
|
@ -7466,7 +7466,16 @@ mod tests {
|
||||||
},
|
},
|
||||||
Some(tree_sitter_rust::language()),
|
Some(tree_sitter_rust::language()),
|
||||||
);
|
);
|
||||||
let mut fake_servers = language.set_fake_lsp_adapter(Default::default());
|
let mut fake_servers = language.set_fake_lsp_adapter(FakeLspAdapter {
|
||||||
|
capabilities: lsp::ServerCapabilities {
|
||||||
|
rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions {
|
||||||
|
prepare_provider: Some(true),
|
||||||
|
work_done_progress_options: Default::default(),
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
let fs = FakeFs::new(cx.background());
|
let fs = FakeFs::new(cx.background());
|
||||||
fs.insert_tree(
|
fs.insert_tree(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue