Draft the hint render data flow
This commit is contained in:
parent
2ead3de7de
commit
4c3c0eb796
6 changed files with 103 additions and 24 deletions
|
@ -30,6 +30,8 @@ pub use block_map::{
|
|||
BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock,
|
||||
};
|
||||
|
||||
use self::editor_addition_map::InlayHintToRender;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum FoldStatus {
|
||||
Folded,
|
||||
|
@ -286,6 +288,25 @@ impl DisplayMap {
|
|||
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||
}
|
||||
|
||||
pub fn set_inlay_hints(&self, new_hints: &[project::InlayHint], cx: &mut ModelContext<Self>) {
|
||||
let multi_buffer = self.buffer.read(cx);
|
||||
self.editor_addition_map.set_inlay_hints(
|
||||
new_hints
|
||||
.into_iter()
|
||||
.filter_map(|hint| {
|
||||
let buffer = multi_buffer.buffer(hint.buffer_id)?.read(cx);
|
||||
let snapshot = buffer.snapshot();
|
||||
Some(InlayHintToRender {
|
||||
position: editor_addition_map::EditorAdditionPoint(
|
||||
text::ToPoint::to_point(&hint.position, &snapshot),
|
||||
),
|
||||
text: hint.text().trim_end().into(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn tab_size(buffer: &ModelHandle<MultiBuffer>, cx: &mut ModelContext<Self>) -> NonZeroU32 {
|
||||
let language = buffer
|
||||
.read(cx)
|
||||
|
|
|
@ -10,17 +10,20 @@ use super::{
|
|||
TextHighlights,
|
||||
};
|
||||
use gpui::fonts::HighlightStyle;
|
||||
use language::{Chunk, Edit, Point, TextSummary};
|
||||
use language::{Chunk, Edit, Point, Rope, TextSummary};
|
||||
use parking_lot::Mutex;
|
||||
use project::InlayHint;
|
||||
use rand::Rng;
|
||||
use sum_tree::Bias;
|
||||
|
||||
pub struct EditorAdditionMap;
|
||||
pub struct EditorAdditionMap(Mutex<EditorAdditionSnapshot>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EditorAdditionSnapshot {
|
||||
// TODO kb merge these two together
|
||||
pub suggestion_snapshot: SuggestionSnapshot,
|
||||
pub version: usize,
|
||||
hints: Vec<InlayHintToRender>,
|
||||
}
|
||||
|
||||
pub type EditorAdditionEdit = Edit<EditorAdditionOffset>;
|
||||
|
@ -63,6 +66,12 @@ pub struct EditorAdditionChunks<'a> {
|
|||
_z: &'a std::marker::PhantomData<()>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InlayHintToRender {
|
||||
pub(super) position: EditorAdditionPoint,
|
||||
pub(super) text: Rope,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for EditorAdditionChunks<'a> {
|
||||
type Item = Chunk<'a>;
|
||||
|
||||
|
@ -95,7 +104,12 @@ impl EditorAdditionPoint {
|
|||
|
||||
impl EditorAdditionMap {
|
||||
pub fn new(suggestion_snapshot: SuggestionSnapshot) -> (Self, EditorAdditionSnapshot) {
|
||||
todo!("TODO kb")
|
||||
let snapshot = EditorAdditionSnapshot {
|
||||
suggestion_snapshot: suggestion_snapshot.clone(),
|
||||
version: 0,
|
||||
hints: Vec::new(),
|
||||
};
|
||||
(Self(Mutex::new(snapshot.clone())), snapshot)
|
||||
}
|
||||
|
||||
pub fn sync(
|
||||
|
@ -103,14 +117,24 @@ impl EditorAdditionMap {
|
|||
suggestion_snapshot: SuggestionSnapshot,
|
||||
suggestion_edits: Vec<SuggestionEdit>,
|
||||
) -> (EditorAdditionSnapshot, Vec<EditorAdditionEdit>) {
|
||||
todo!("TODO kb")
|
||||
let mut snapshot = self.0.lock();
|
||||
|
||||
if snapshot.suggestion_snapshot.version != suggestion_snapshot.version {
|
||||
snapshot.version += 1;
|
||||
}
|
||||
|
||||
let editor_addition_edits = Vec::new();
|
||||
{
|
||||
todo!("TODO kb")
|
||||
}
|
||||
|
||||
snapshot.suggestion_snapshot = suggestion_snapshot;
|
||||
|
||||
(snapshot.clone(), editor_addition_edits)
|
||||
}
|
||||
|
||||
pub fn randomly_mutate(
|
||||
&self,
|
||||
rng: &mut impl Rng,
|
||||
) -> (EditorAdditionSnapshot, Vec<EditorAdditionEdit>) {
|
||||
todo!("TODO kb")
|
||||
pub fn set_inlay_hints(&self, new_hints: Vec<InlayHintToRender>) {
|
||||
self.0.lock().hints = new_hints;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -761,11 +761,13 @@ mod tests {
|
|||
let (suggestion_map, _) = SuggestionMap::new(fold_snapshot);
|
||||
let (suggestion_snapshot, _) = suggestion_map.randomly_mutate(&mut rng);
|
||||
log::info!("SuggestionMap text: {:?}", suggestion_snapshot.text());
|
||||
let (editor_addition_map, _) = EditorAdditionMap::new(suggestion_snapshot.clone());
|
||||
let (suggestion_snapshot, _) = editor_addition_map.randomly_mutate(&mut rng);
|
||||
log::info!("EditorAdditionMap text: {:?}", suggestion_snapshot.text());
|
||||
let (_, editor_addition_snapshot) = EditorAdditionMap::new(suggestion_snapshot.clone());
|
||||
log::info!(
|
||||
"EditorAdditionMap text: {:?}",
|
||||
editor_addition_snapshot.text()
|
||||
);
|
||||
|
||||
let (tab_map, _) = TabMap::new(suggestion_snapshot.clone(), tab_size);
|
||||
let (tab_map, _) = TabMap::new(editor_addition_snapshot.clone(), tab_size);
|
||||
let tabs_snapshot = tab_map.set_max_expansion_column(32);
|
||||
|
||||
let text = text::Rope::from(tabs_snapshot.text().as_str());
|
||||
|
@ -803,7 +805,7 @@ mod tests {
|
|||
);
|
||||
|
||||
let mut actual_summary = tabs_snapshot.text_summary_for_range(start..end);
|
||||
if tab_size.get() > 1 && suggestion_snapshot.text().contains('\t') {
|
||||
if tab_size.get() > 1 && editor_addition_snapshot.text().contains('\t') {
|
||||
actual_summary.longest_row = expected_summary.longest_row;
|
||||
actual_summary.longest_row_chars = expected_summary.longest_row_chars;
|
||||
}
|
||||
|
|
|
@ -1169,11 +1169,19 @@ impl InlayHintState {
|
|||
Self::first_timestamp_newer(timestamp, ¤t_timestamp)
|
||||
}
|
||||
|
||||
fn update_if_newer(&self, new_hints: Vec<InlayHint>, new_timestamp: HashMap<usize, Global>) {
|
||||
fn update_if_newer(
|
||||
&self,
|
||||
new_hints: Vec<InlayHint>,
|
||||
new_timestamp: HashMap<usize, Global>,
|
||||
) -> bool {
|
||||
let mut guard = self.0.write();
|
||||
if Self::first_timestamp_newer(&new_timestamp, &guard.0) {
|
||||
guard.0 = new_timestamp;
|
||||
guard.1 = new_hints;
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2688,7 +2696,7 @@ impl Editor {
|
|||
|
||||
let inlay_hints_storage = Arc::clone(&self.inlay_hints);
|
||||
if inlay_hints_storage.is_newer(&new_timestamp) {
|
||||
cx.spawn(|_, _| async move {
|
||||
cx.spawn(|editor, mut cx| async move {
|
||||
let mut new_hints = Vec::new();
|
||||
for task_result in futures::future::join_all(hint_fetch_tasks).await {
|
||||
match task_result {
|
||||
|
@ -2696,7 +2704,18 @@ impl Editor {
|
|||
Err(e) => error!("Failed to update hints for buffer: {e:#}"),
|
||||
}
|
||||
}
|
||||
inlay_hints_storage.update_if_newer(new_hints, new_timestamp);
|
||||
|
||||
// TODO kb another odd clone, can be avoid all this? hide hints behind a handle?
|
||||
if inlay_hints_storage.update_if_newer(new_hints.clone(), new_timestamp) {
|
||||
editor
|
||||
.update(&mut cx, |editor, cx| {
|
||||
editor.display_map.update(cx, |display_map, cx| {
|
||||
display_map.set_inlay_hints(&new_hints, cx)
|
||||
});
|
||||
})
|
||||
.log_err()
|
||||
.unwrap_or(())
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
@ -1834,6 +1834,7 @@ impl LspCommand for InlayHints {
|
|||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|lsp_hint| InlayHint {
|
||||
buffer_id: buffer.id() as u64,
|
||||
position: origin_buffer.anchor_after(
|
||||
origin_buffer
|
||||
.clip_point_utf16(point_from_lsp(lsp_hint.position), Bias::Left),
|
||||
|
@ -2006,6 +2007,7 @@ impl LspCommand for InlayHints {
|
|||
let mut hints = Vec::new();
|
||||
for message_hint in message.hints {
|
||||
let hint = InlayHint {
|
||||
buffer_id: buffer.id() as u64,
|
||||
position: message_hint
|
||||
.position
|
||||
.and_then(language::proto::deserialize_anchor)
|
||||
|
|
|
@ -29,6 +29,7 @@ use gpui::{
|
|||
AnyModelHandle, AppContext, AsyncAppContext, BorrowAppContext, Entity, ModelContext,
|
||||
ModelHandle, Task, WeakModelHandle,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
language_settings::{language_settings, FormatOnSave, Formatter},
|
||||
point_to_lsp,
|
||||
|
@ -320,46 +321,56 @@ pub struct DiagnosticSummary {
|
|||
pub warning_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Location {
|
||||
pub buffer: ModelHandle<Buffer>,
|
||||
pub range: Range<language::Anchor>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InlayHint {
|
||||
pub buffer_id: u64,
|
||||
pub position: Anchor,
|
||||
pub label: InlayHintLabel,
|
||||
pub kind: Option<String>,
|
||||
pub tooltip: Option<InlayHintTooltip>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
impl InlayHint {
|
||||
pub fn text(&self) -> String {
|
||||
match &self.label {
|
||||
InlayHintLabel::String(s) => s.to_owned(),
|
||||
InlayHintLabel::LabelParts(parts) => parts.iter().map(|part| &part.value).join(""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum InlayHintLabel {
|
||||
String(String),
|
||||
LabelParts(Vec<InlayHintLabelPart>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct InlayHintLabelPart {
|
||||
pub value: String,
|
||||
pub tooltip: Option<InlayHintLabelPartTooltip>,
|
||||
pub location: Option<Location>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum InlayHintTooltip {
|
||||
String(String),
|
||||
MarkupContent(MarkupContent),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum InlayHintLabelPartTooltip {
|
||||
String(String),
|
||||
MarkupContent(MarkupContent),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MarkupContent {
|
||||
pub kind: String,
|
||||
pub value: String,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue