Highlight whitespace-only inline completions with background (#21954)

Noticed that whitespace-only insertions are really hard to make out, so
this changes it to make them visible by giving them a green background.

![screenshot-2024-12-13-10 49
09@2x](https://github.com/user-attachments/assets/10d83067-46f2-4cb5-97fa-0f44d254890d)


Release Notes:

- N/A

---------

Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
Thorsten Ball 2024-12-13 13:40:34 +01:00 committed by GitHub
parent 6838b6203a
commit 2f722e63a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 29 deletions

View file

@ -11,8 +11,8 @@ use futures::{
use fuzzy::StringMatchCandidate; use fuzzy::StringMatchCandidate;
use gpui::{ use gpui::{
actions, point, size, transparent_black, Action, AppContext, BackgroundExecutor, Bounds, actions, point, size, transparent_black, Action, AppContext, BackgroundExecutor, Bounds,
EventEmitter, Global, HighlightStyle, PromptLevel, ReadGlobal, Subscription, Task, TextStyle, EventEmitter, Global, PromptLevel, ReadGlobal, Subscription, Task, TextStyle, TitlebarOptions,
TitlebarOptions, UpdateGlobal, View, WindowBounds, WindowHandle, WindowOptions, UpdateGlobal, View, WindowBounds, WindowHandle, WindowOptions,
}; };
use heed::{ use heed::{
types::{SerdeBincode, SerdeJson, Str}, types::{SerdeBincode, SerdeJson, Str},
@ -928,10 +928,8 @@ impl PromptLibrary {
status: cx.theme().status().clone(), status: cx.theme().status().clone(),
inlay_hints_style: inlay_hints_style:
editor::make_inlay_hints_style(cx), editor::make_inlay_hints_style(cx),
suggestions_style: HighlightStyle { inline_completion_styles:
color: Some(cx.theme().status().predictive), editor::make_suggestion_styles(cx),
..HighlightStyle::default()
},
..EditorStyle::default() ..EditorStyle::default()
}, },
)), )),

View file

@ -535,10 +535,16 @@ pub(crate) struct Highlights<'a> {
pub styles: HighlightStyles, pub styles: HighlightStyles,
} }
#[derive(Clone, Copy, Debug)]
pub struct InlineCompletionStyles {
pub insertion: HighlightStyle,
pub whitespace: HighlightStyle,
}
#[derive(Default, Debug, Clone, Copy)] #[derive(Default, Debug, Clone, Copy)]
pub struct HighlightStyles { pub struct HighlightStyles {
pub inlay_hint: Option<HighlightStyle>, pub inlay_hint: Option<HighlightStyle>,
pub suggestion: Option<HighlightStyle>, pub inline_completion: Option<InlineCompletionStyles>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -859,7 +865,7 @@ impl DisplaySnapshot {
language_aware, language_aware,
HighlightStyles { HighlightStyles {
inlay_hint: Some(editor_style.inlay_hints_style), inlay_hint: Some(editor_style.inlay_hints_style),
suggestion: Some(editor_style.suggestions_style), inline_completion: Some(editor_style.inline_completion_styles),
}, },
) )
.flat_map(|chunk| { .flat_map(|chunk| {

View file

@ -62,9 +62,9 @@ impl Inlay {
} }
} }
pub fn suggestion<T: Into<Rope>>(id: usize, position: Anchor, text: T) -> Self { pub fn inline_completion<T: Into<Rope>>(id: usize, position: Anchor, text: T) -> Self {
Self { Self {
id: InlayId::Suggestion(id), id: InlayId::InlineCompletion(id),
position, position,
text: text.into(), text: text.into(),
} }
@ -346,7 +346,15 @@ impl<'a> Iterator for InlayChunks<'a> {
} }
let mut highlight_style = match inlay.id { let mut highlight_style = match inlay.id {
InlayId::Suggestion(_) => self.highlight_styles.suggestion, InlayId::InlineCompletion(_) => {
self.highlight_styles.inline_completion.map(|s| {
if inlay.text.chars().all(|c| c.is_whitespace()) {
s.whitespace
} else {
s.insertion
}
})
}
InlayId::Hint(_) => self.highlight_styles.inlay_hint, InlayId::Hint(_) => self.highlight_styles.inlay_hint,
}; };
let next_inlay_highlight_endpoint; let next_inlay_highlight_endpoint;
@ -693,7 +701,7 @@ impl InlayMap {
let inlay_id = if i % 2 == 0 { let inlay_id = if i % 2 == 0 {
InlayId::Hint(post_inc(next_inlay_id)) InlayId::Hint(post_inc(next_inlay_id))
} else { } else {
InlayId::Suggestion(post_inc(next_inlay_id)) InlayId::InlineCompletion(post_inc(next_inlay_id))
}; };
log::info!( log::info!(
"creating inlay {:?} at buffer offset {} with bias {:?} and text {:?}", "creating inlay {:?} at buffer offset {} with bias {:?} and text {:?}",
@ -1389,7 +1397,7 @@ mod tests {
text: "|123|".into(), text: "|123|".into(),
}, },
Inlay { Inlay {
id: InlayId::Suggestion(post_inc(&mut next_inlay_id)), id: InlayId::InlineCompletion(post_inc(&mut next_inlay_id)),
position: buffer.read(cx).snapshot(cx).anchor_after(3), position: buffer.read(cx).snapshot(cx).anchor_after(3),
text: "|456|".into(), text: "|456|".into(),
}, },
@ -1605,7 +1613,7 @@ mod tests {
text: "|456|".into(), text: "|456|".into(),
}, },
Inlay { Inlay {
id: InlayId::Suggestion(post_inc(&mut next_inlay_id)), id: InlayId::InlineCompletion(post_inc(&mut next_inlay_id)),
position: buffer.read(cx).snapshot(cx).anchor_before(7), position: buffer.read(cx).snapshot(cx).anchor_before(7),
text: "\n|567|\n".into(), text: "\n|567|\n".into(),
}, },

View file

@ -259,14 +259,14 @@ pub fn render_parsed_markdown(
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) enum InlayId { pub(crate) enum InlayId {
Suggestion(usize), InlineCompletion(usize),
Hint(usize), Hint(usize),
} }
impl InlayId { impl InlayId {
fn id(&self) -> usize { fn id(&self) -> usize {
match self { match self {
Self::Suggestion(id) => *id, Self::InlineCompletion(id) => *id,
Self::Hint(id) => *id, Self::Hint(id) => *id,
} }
} }
@ -405,7 +405,7 @@ pub struct EditorStyle {
pub syntax: Arc<SyntaxTheme>, pub syntax: Arc<SyntaxTheme>,
pub status: StatusColors, pub status: StatusColors,
pub inlay_hints_style: HighlightStyle, pub inlay_hints_style: HighlightStyle,
pub suggestions_style: HighlightStyle, pub inline_completion_styles: InlineCompletionStyles,
pub unnecessary_code_fade: f32, pub unnecessary_code_fade: f32,
} }
@ -422,7 +422,10 @@ impl Default for EditorStyle {
// style and retrieve them directly from the theme. // style and retrieve them directly from the theme.
status: StatusColors::dark(), status: StatusColors::dark(),
inlay_hints_style: HighlightStyle::default(), inlay_hints_style: HighlightStyle::default(),
suggestions_style: HighlightStyle::default(), inline_completion_styles: InlineCompletionStyles {
insertion: HighlightStyle::default(),
whitespace: HighlightStyle::default(),
},
unnecessary_code_fade: Default::default(), unnecessary_code_fade: Default::default(),
} }
} }
@ -440,6 +443,19 @@ pub fn make_inlay_hints_style(cx: &WindowContext) -> HighlightStyle {
} }
} }
pub fn make_suggestion_styles(cx: &WindowContext) -> InlineCompletionStyles {
InlineCompletionStyles {
insertion: HighlightStyle {
color: Some(cx.theme().status().predictive),
..HighlightStyle::default()
},
whitespace: HighlightStyle {
background_color: Some(cx.theme().status().created_background),
..HighlightStyle::default()
},
}
}
type CompletionId = usize; type CompletionId = usize;
enum InlineCompletion { enum InlineCompletion {
@ -4735,7 +4751,7 @@ impl Editor {
{ {
let mut inlays = Vec::new(); let mut inlays = Vec::new();
for (range, new_text) in &edits { for (range, new_text) in &edits {
let inlay = Inlay::suggestion( let inlay = Inlay::inline_completion(
post_inc(&mut self.next_inlay_id), post_inc(&mut self.next_inlay_id),
range.start, range.start,
new_text.as_str(), new_text.as_str(),
@ -9901,10 +9917,9 @@ impl Editor {
font_weight: Some(FontWeight::BOLD), font_weight: Some(FontWeight::BOLD),
..make_inlay_hints_style(cx) ..make_inlay_hints_style(cx)
}, },
suggestions_style: HighlightStyle { inline_completion_styles: make_suggestion_styles(
color: Some(cx.theme().status().predictive), cx,
..HighlightStyle::default() ),
},
..EditorStyle::default() ..EditorStyle::default()
}, },
)) ))
@ -13905,10 +13920,7 @@ impl Render for Editor {
syntax: cx.theme().syntax().clone(), syntax: cx.theme().syntax().clone(),
status: cx.theme().status().clone(), status: cx.theme().status().clone(),
inlay_hints_style: make_inlay_hints_style(cx), inlay_hints_style: make_inlay_hints_style(cx),
suggestions_style: HighlightStyle { inline_completion_styles: make_suggestion_styles(cx),
color: Some(cx.theme().status().predictive),
..HighlightStyle::default()
},
unnecessary_code_fade: ThemeSettings::get_global(cx).unnecessary_code_fade, unnecessary_code_fade: ThemeSettings::get_global(cx).unnecessary_code_fade,
}, },
) )

View file

@ -841,12 +841,12 @@ mod tests {
.flat_map(|offset| { .flat_map(|offset| {
[ [
Inlay { Inlay {
id: InlayId::Suggestion(post_inc(&mut id)), id: InlayId::InlineCompletion(post_inc(&mut id)),
position: buffer_snapshot.anchor_at(offset, Bias::Left), position: buffer_snapshot.anchor_at(offset, Bias::Left),
text: "test".into(), text: "test".into(),
}, },
Inlay { Inlay {
id: InlayId::Suggestion(post_inc(&mut id)), id: InlayId::InlineCompletion(post_inc(&mut id)),
position: buffer_snapshot.anchor_at(offset, Bias::Right), position: buffer_snapshot.anchor_at(offset, Bias::Right),
text: "test".into(), text: "test".into(),
}, },