Implement grapheme support for supermaven completions (#18279)
Closes [#18278](https://github.com/zed-industries/zed/issues/18278) Release Notes: - Fixed a panic when graphemes are included in supermaven completions
This commit is contained in:
parent
437bcc0ce6
commit
e87d6da2a6
3 changed files with 14 additions and 10 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -11006,6 +11006,7 @@ dependencies = [
|
||||||
"text",
|
"text",
|
||||||
"theme",
|
"theme",
|
||||||
"ui",
|
"ui",
|
||||||
|
"unicode-segmentation",
|
||||||
"util",
|
"util",
|
||||||
"windows 0.58.0",
|
"windows 0.58.0",
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,6 +29,7 @@ supermaven_api.workspace = true
|
||||||
smol.workspace = true
|
smol.workspace = true
|
||||||
text.workspace = true
|
text.workspace = true
|
||||||
ui.workspace = true
|
ui.workspace = true
|
||||||
|
unicode-segmentation.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use text::{ToOffset, ToPoint};
|
use text::{ToOffset, ToPoint};
|
||||||
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
pub const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
pub const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(75);
|
||||||
|
|
||||||
|
@ -54,33 +55,34 @@ fn completion_state_from_diff(
|
||||||
) -> CompletionProposal {
|
) -> CompletionProposal {
|
||||||
let buffer_text = snapshot
|
let buffer_text = snapshot
|
||||||
.text_for_range(delete_range.clone())
|
.text_for_range(delete_range.clone())
|
||||||
.collect::<String>()
|
.collect::<String>();
|
||||||
.chars()
|
|
||||||
.collect::<Vec<char>>();
|
|
||||||
|
|
||||||
let mut inlays: Vec<InlayProposal> = Vec::new();
|
let mut inlays: Vec<InlayProposal> = Vec::new();
|
||||||
|
|
||||||
let completion = completion_text.chars().collect::<Vec<char>>();
|
let completion_graphemes: Vec<&str> = completion_text.graphemes(true).collect();
|
||||||
|
let buffer_graphemes: Vec<&str> = buffer_text.graphemes(true).collect();
|
||||||
|
|
||||||
let mut offset = position.to_offset(&snapshot);
|
let mut offset = position.to_offset(&snapshot);
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
while i < completion.len() && j < buffer_text.len() {
|
while i < completion_graphemes.len() && j < buffer_graphemes.len() {
|
||||||
// find the next instance of the buffer text in the completion text.
|
// find the next instance of the buffer text in the completion text.
|
||||||
let k = completion[i..].iter().position(|c| *c == buffer_text[j]);
|
let k = completion_graphemes[i..]
|
||||||
|
.iter()
|
||||||
|
.position(|c| *c == buffer_graphemes[j]);
|
||||||
match k {
|
match k {
|
||||||
Some(k) => {
|
Some(k) => {
|
||||||
if k != 0 {
|
if k != 0 {
|
||||||
// the range from the current position to item is an inlay.
|
// the range from the current position to item is an inlay.
|
||||||
inlays.push(InlayProposal::Suggestion(
|
inlays.push(InlayProposal::Suggestion(
|
||||||
snapshot.anchor_after(offset),
|
snapshot.anchor_after(offset),
|
||||||
completion_text[i..i + k].into(),
|
completion_graphemes[i..i + k].join("").into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
i += k + 1;
|
i += k + 1;
|
||||||
j += 1;
|
j += 1;
|
||||||
offset.add_assign(1);
|
offset.add_assign(buffer_graphemes[j - 1].len());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// there are no more matching completions, so drop the remaining
|
// there are no more matching completions, so drop the remaining
|
||||||
|
@ -90,11 +92,11 @@ fn completion_state_from_diff(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if j == buffer_text.len() && i < completion.len() {
|
if j == buffer_graphemes.len() && i < completion_graphemes.len() {
|
||||||
// there is leftover completion text, so drop it as an inlay.
|
// there is leftover completion text, so drop it as an inlay.
|
||||||
inlays.push(InlayProposal::Suggestion(
|
inlays.push(InlayProposal::Suggestion(
|
||||||
snapshot.anchor_after(offset),
|
snapshot.anchor_after(offset),
|
||||||
completion_text[i..completion_text.len()].into(),
|
completion_graphemes[i..].join("").into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue