Reduce amount of allocations in RustLsp label handling (#35786)
There can be a lot of completions after all Release Notes: - N/A
This commit is contained in:
parent
c397027ec2
commit
4dbd24d75f
9 changed files with 40 additions and 65 deletions
|
@ -876,7 +876,7 @@ async fn test_random_diagnostics_with_inlays(cx: &mut TestAppContext, mut rng: S
|
||||||
vec![Inlay::edit_prediction(
|
vec![Inlay::edit_prediction(
|
||||||
post_inc(&mut next_inlay_id),
|
post_inc(&mut next_inlay_id),
|
||||||
snapshot.buffer_snapshot.anchor_before(position),
|
snapshot.buffer_snapshot.anchor_before(position),
|
||||||
format!("Test inlay {next_inlay_id}"),
|
Rope::from_iter(["Test inlay ", "next_inlay_id"]),
|
||||||
)],
|
)],
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
|
|
@ -48,16 +48,16 @@ pub struct Inlay {
|
||||||
impl Inlay {
|
impl Inlay {
|
||||||
pub fn hint(id: usize, position: Anchor, hint: &project::InlayHint) -> Self {
|
pub fn hint(id: usize, position: Anchor, hint: &project::InlayHint) -> Self {
|
||||||
let mut text = hint.text();
|
let mut text = hint.text();
|
||||||
if hint.padding_right && !text.ends_with(' ') {
|
if hint.padding_right && text.chars_at(text.len().saturating_sub(1)).next() != Some(' ') {
|
||||||
text.push(' ');
|
text.push(" ");
|
||||||
}
|
}
|
||||||
if hint.padding_left && !text.starts_with(' ') {
|
if hint.padding_left && text.chars_at(0).next() != Some(' ') {
|
||||||
text.insert(0, ' ');
|
text.push_front(" ");
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
id: InlayId::Hint(id),
|
id: InlayId::Hint(id),
|
||||||
position,
|
position,
|
||||||
text: text.into(),
|
text,
|
||||||
color: None,
|
color: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -737,13 +737,13 @@ impl InlayMap {
|
||||||
Inlay::mock_hint(
|
Inlay::mock_hint(
|
||||||
post_inc(next_inlay_id),
|
post_inc(next_inlay_id),
|
||||||
snapshot.buffer.anchor_at(position, bias),
|
snapshot.buffer.anchor_at(position, bias),
|
||||||
text.clone(),
|
&text,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Inlay::edit_prediction(
|
Inlay::edit_prediction(
|
||||||
post_inc(next_inlay_id),
|
post_inc(next_inlay_id),
|
||||||
snapshot.buffer.anchor_at(position, bias),
|
snapshot.buffer.anchor_at(position, bias),
|
||||||
text.clone(),
|
&text,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let inlay_id = next_inlay.id;
|
let inlay_id = next_inlay.id;
|
||||||
|
@ -1694,7 +1694,7 @@ mod tests {
|
||||||
(offset, inlay.clone())
|
(offset, inlay.clone())
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let mut expected_text = Rope::from(buffer_snapshot.text());
|
let mut expected_text = Rope::from(&buffer_snapshot.text());
|
||||||
for (offset, inlay) in inlays.iter().rev() {
|
for (offset, inlay) in inlays.iter().rev() {
|
||||||
expected_text.replace(*offset..*offset, &inlay.text.to_string());
|
expected_text.replace(*offset..*offset, &inlay.text.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3546,7 +3546,7 @@ pub mod tests {
|
||||||
let excerpt_hints = excerpt_hints.read();
|
let excerpt_hints = excerpt_hints.read();
|
||||||
for id in &excerpt_hints.ordered_hints {
|
for id in &excerpt_hints.ordered_hints {
|
||||||
let hint = &excerpt_hints.hints_by_id[id];
|
let hint = &excerpt_hints.hints_by_id[id];
|
||||||
let mut label = hint.text();
|
let mut label = hint.text().to_string();
|
||||||
if hint.padding_left {
|
if hint.padding_left {
|
||||||
label.insert(0, ' ');
|
label.insert(0, ' ');
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl Editor {
|
||||||
|
|
||||||
if let Some(language) = language {
|
if let Some(language) = language {
|
||||||
for signature in &mut signature_help.signatures {
|
for signature in &mut signature_help.signatures {
|
||||||
let text = Rope::from(signature.label.to_string());
|
let text = Rope::from(signature.label.as_ref());
|
||||||
let highlights = language
|
let highlights = language
|
||||||
.highlight_text(&text, 0..signature.label.len())
|
.highlight_text(&text, 0..signature.label.len())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -341,7 +341,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let name = &completion.label;
|
let name = &completion.label;
|
||||||
let text = format!("{name}: {signature}");
|
let text = format!("{name}: {signature}");
|
||||||
let prefix = "struct S { ";
|
let prefix = "struct S { ";
|
||||||
let source = Rope::from(format!("{prefix}{text} }}"));
|
let source = Rope::from_iter([prefix, &text, " }"]);
|
||||||
let runs =
|
let runs =
|
||||||
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
||||||
mk_label(text, runs)
|
mk_label(text, runs)
|
||||||
|
@ -353,7 +353,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
let name = &completion.label;
|
let name = &completion.label;
|
||||||
let text = format!("{name}: {signature}",);
|
let text = format!("{name}: {signature}",);
|
||||||
let prefix = "let ";
|
let prefix = "let ";
|
||||||
let source = Rope::from(format!("{prefix}{text} = ();"));
|
let source = Rope::from_iter([prefix, &text, " = ();"]);
|
||||||
let runs =
|
let runs =
|
||||||
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
language.highlight_text(&source, prefix.len()..prefix.len() + text.len());
|
||||||
mk_label(text, runs)
|
mk_label(text, runs)
|
||||||
|
@ -387,7 +387,7 @@ impl LspAdapter for RustLspAdapter {
|
||||||
&completion.label
|
&completion.label
|
||||||
};
|
};
|
||||||
let text = format!("{label}{suffix}");
|
let text = format!("{label}{suffix}");
|
||||||
let source = Rope::from(format!("{prefix} {text} {{}}"));
|
let source = Rope::from_iter([prefix, " ", &text, " {}"]);
|
||||||
let run_start = prefix.len() + 1;
|
let run_start = prefix.len() + 1;
|
||||||
let runs = language.highlight_text(&source, run_start..run_start + text.len());
|
let runs = language.highlight_text(&source, run_start..run_start + text.len());
|
||||||
mk_label(text, runs)
|
mk_label(text, runs)
|
||||||
|
@ -450,55 +450,22 @@ impl LspAdapter for RustLspAdapter {
|
||||||
kind: lsp::SymbolKind,
|
kind: lsp::SymbolKind,
|
||||||
language: &Arc<Language>,
|
language: &Arc<Language>,
|
||||||
) -> Option<CodeLabel> {
|
) -> Option<CodeLabel> {
|
||||||
let (text, filter_range, display_range) = match kind {
|
let (prefix, suffix) = match kind {
|
||||||
lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
|
lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => ("fn ", " () {}"),
|
||||||
let text = format!("fn {} () {{}}", name);
|
lsp::SymbolKind::STRUCT => ("struct ", " {}"),
|
||||||
let filter_range = 3..3 + name.len();
|
lsp::SymbolKind::ENUM => ("enum ", " {}"),
|
||||||
let display_range = 0..filter_range.end;
|
lsp::SymbolKind::INTERFACE => ("trait ", " {}"),
|
||||||
(text, filter_range, display_range)
|
lsp::SymbolKind::CONSTANT => ("const ", ": () = ();"),
|
||||||
}
|
lsp::SymbolKind::MODULE => ("mod ", " {}"),
|
||||||
lsp::SymbolKind::STRUCT => {
|
lsp::SymbolKind::TYPE_PARAMETER => ("type ", " {}"),
|
||||||
let text = format!("struct {} {{}}", name);
|
|
||||||
let filter_range = 7..7 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
lsp::SymbolKind::ENUM => {
|
|
||||||
let text = format!("enum {} {{}}", name);
|
|
||||||
let filter_range = 5..5 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
lsp::SymbolKind::INTERFACE => {
|
|
||||||
let text = format!("trait {} {{}}", name);
|
|
||||||
let filter_range = 6..6 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
lsp::SymbolKind::CONSTANT => {
|
|
||||||
let text = format!("const {}: () = ();", name);
|
|
||||||
let filter_range = 6..6 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
lsp::SymbolKind::MODULE => {
|
|
||||||
let text = format!("mod {} {{}}", name);
|
|
||||||
let filter_range = 4..4 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
lsp::SymbolKind::TYPE_PARAMETER => {
|
|
||||||
let text = format!("type {} {{}}", name);
|
|
||||||
let filter_range = 5..5 + name.len();
|
|
||||||
let display_range = 0..filter_range.end;
|
|
||||||
(text, filter_range, display_range)
|
|
||||||
}
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let filter_range = prefix.len()..prefix.len() + name.len();
|
||||||
|
let display_range = 0..filter_range.end;
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
|
runs: language.highlight_text(&Rope::from_iter([prefix, name, suffix]), display_range),
|
||||||
text: text[display_range].to_string(),
|
text: format!("{prefix}{name}"),
|
||||||
filter_range,
|
filter_range,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,6 @@ use gpui::{
|
||||||
App, AppContext, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Hsla, SharedString,
|
App, AppContext, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Hsla, SharedString,
|
||||||
Task, WeakEntity, Window,
|
Task, WeakEntity, Window,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
|
||||||
use language::{
|
use language::{
|
||||||
Buffer, BufferEvent, Capability, CodeLabel, CursorShape, DiagnosticSourceKind, Language,
|
Buffer, BufferEvent, Capability, CodeLabel, CursorShape, DiagnosticSourceKind, Language,
|
||||||
LanguageName, LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16, Toolchain, ToolchainList,
|
LanguageName, LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16, Toolchain, ToolchainList,
|
||||||
|
@ -113,7 +112,7 @@ use std::{
|
||||||
|
|
||||||
use task_store::TaskStore;
|
use task_store::TaskStore;
|
||||||
use terminals::Terminals;
|
use terminals::Terminals;
|
||||||
use text::{Anchor, BufferId, OffsetRangeExt, Point};
|
use text::{Anchor, BufferId, OffsetRangeExt, Point, Rope};
|
||||||
use toolchain_store::EmptyToolchainStore;
|
use toolchain_store::EmptyToolchainStore;
|
||||||
use util::{
|
use util::{
|
||||||
ResultExt as _,
|
ResultExt as _,
|
||||||
|
@ -668,10 +667,10 @@ pub enum ResolveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlayHint {
|
impl InlayHint {
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> Rope {
|
||||||
match &self.label {
|
match &self.label {
|
||||||
InlayHintLabel::String(s) => s.to_owned(),
|
InlayHintLabel::String(s) => Rope::from(s),
|
||||||
InlayHintLabel::LabelParts(parts) => parts.iter().map(|part| &part.value).join(""),
|
InlayHintLabel::LabelParts(parts) => parts.iter().map(|part| &*part.value).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ use git::{
|
||||||
use git2::RepositoryInitOptions;
|
use git2::RepositoryInitOptions;
|
||||||
use gpui::{App, BackgroundExecutor, SemanticVersion, UpdateGlobal};
|
use gpui::{App, BackgroundExecutor, SemanticVersion, UpdateGlobal};
|
||||||
use http_client::Url;
|
use http_client::Url;
|
||||||
|
use itertools::Itertools;
|
||||||
use language::{
|
use language::{
|
||||||
Diagnostic, DiagnosticEntry, DiagnosticSet, DiskState, FakeLspAdapter, LanguageConfig,
|
Diagnostic, DiagnosticEntry, DiagnosticSet, DiskState, FakeLspAdapter, LanguageConfig,
|
||||||
LanguageMatcher, LanguageName, LineEnding, OffsetRangeExt, Point, ToPoint,
|
LanguageMatcher, LanguageName, LineEnding, OffsetRangeExt, Point, ToPoint,
|
||||||
|
|
|
@ -471,11 +471,19 @@ impl<'a> FromIterator<&'a str> for Rope {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Rope {
|
impl From<String> for Rope {
|
||||||
|
#[inline(always)]
|
||||||
fn from(text: String) -> Self {
|
fn from(text: String) -> Self {
|
||||||
Rope::from(text.as_str())
|
Rope::from(text.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&String> for Rope {
|
||||||
|
#[inline(always)]
|
||||||
|
fn from(text: &String) -> Self {
|
||||||
|
Rope::from(text.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Rope {
|
impl fmt::Display for Rope {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for chunk in self.chunks() {
|
for chunk in self.chunks() {
|
||||||
|
|
|
@ -713,7 +713,7 @@ impl Buffer {
|
||||||
let mut base_text = base_text.into();
|
let mut base_text = base_text.into();
|
||||||
let line_ending = LineEnding::detect(&base_text);
|
let line_ending = LineEnding::detect(&base_text);
|
||||||
LineEnding::normalize(&mut base_text);
|
LineEnding::normalize(&mut base_text);
|
||||||
Self::new_normalized(replica_id, remote_id, line_ending, Rope::from(base_text))
|
Self::new_normalized(replica_id, remote_id, line_ending, Rope::from(&*base_text))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_normalized(
|
pub fn new_normalized(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue