@@ -7896,6 +7896,8 @@ async fn test_mutual_editor_inlay_hint_cache_update(
.unwrap();
let workspace_a = client_a.build_workspace(&project_a, cx_a);
+ cx_a.foreground().start_waiting();
+
let editor_a = workspace_a
.update(cx_a, |workspace, cx| {
workspace.open_path((worktree_id, "main.rs"), None, true, cx)
@@ -7904,58 +7906,8 @@ async fn test_mutual_editor_inlay_hint_cache_update(
.unwrap()
.downcast::<Editor>()
.unwrap();
- cx_a.foreground().run_until_parked();
- editor_a.update(cx_a, |editor, _| {
- assert!(
- extract_hint_labels(editor).is_empty(),
- "No inlays should be in the new cache"
- );
- let inlay_cache = editor.inlay_hint_cache();
- assert_eq!(
- inlay_cache.allowed_hint_kinds, allowed_hint_kinds,
- "Cache should use editor settings to get the allowed hint kinds"
- );
- assert_eq!(
- inlay_cache.version, 0,
- "New cache should have no version updates"
- );
- });
- let workspace_b = client_b.build_workspace(&project_b, cx_b);
- let editor_b = workspace_b
- .update(cx_b, |workspace, cx| {
- workspace.open_path((worktree_id, "main.rs"), None, true, cx)
- })
- .await
- .unwrap()
- .downcast::<Editor>()
- .unwrap();
- cx_b.foreground().run_until_parked();
- editor_b.update(cx_b, |editor, _| {
- assert!(
- extract_hint_labels(editor).is_empty(),
- "No inlays should be in the new cache"
- );
- let inlay_cache = editor.inlay_hint_cache();
- assert_eq!(
- inlay_cache.allowed_hint_kinds, allowed_hint_kinds,
- "Cache should use editor settings to get the allowed hint kinds"
- );
- assert_eq!(
- inlay_cache.version, 0,
- "New cache should have no version updates"
- );
- });
-
- cx_a.foreground().start_waiting();
- let mut edits_made = 0;
let fake_language_server = fake_language_servers.next().await.unwrap();
- editor_b.update(cx_b, |editor, cx| {
- editor.change_selections(None, cx, |s| s.select_ranges([13..13].clone()));
- editor.handle_input(":", cx);
- cx.focus(&editor_b);
- edits_made += 1;
- });
let next_call_id = Arc::new(AtomicU32::new(0));
fake_language_server
.handle_request::<lsp::request::InlayHintRequest, _, _>(move |params, _| {
@@ -7992,37 +7944,77 @@ async fn test_mutual_editor_inlay_hint_cache_update(
cx_a.foreground().finish_waiting();
cx_a.foreground().run_until_parked();
- fn extract_hint_labels(editor: &Editor) -> Vec<String> {
- let mut labels = Vec::new();
- for (_, excerpt_hints) in &editor.inlay_hint_cache().hints {
- let excerpt_hints = excerpt_hints.read();
- for (_, inlay) in excerpt_hints.hints.iter() {
- match &inlay.label {
- project::InlayHintLabel::String(s) => labels.push(s.to_string()),
- _ => unreachable!(),
- }
- }
- }
- labels
- }
-
+ let mut edits_made = 0;
+ edits_made += 1;
editor_a.update(cx_a, |editor, _| {
assert_eq!(
vec!["0".to_string()],
extract_hint_labels(editor),
- "Host should get hints from the 1st edit and 1st LSP query"
+ "Host should get its first hints when opens an editor"
);
let inlay_cache = editor.inlay_hint_cache();
- assert_eq!(inlay_cache.allowed_hint_kinds, allowed_hint_kinds, "Inlay kinds settings never change during the test");
+ assert_eq!(
+ inlay_cache.allowed_hint_kinds, allowed_hint_kinds,
+ "Cache should use editor settings to get the allowed hint kinds"
+ );
assert_eq!(
inlay_cache.version, edits_made,
- "Each editor should track its own inlay cache history, which should be incremented after every cache/view change"
+ "Host editor should track its own inlay cache history, which should be incremented after every cache/view change"
);
});
+ let workspace_b = client_b.build_workspace(&project_b, cx_b);
+ let editor_b = workspace_b
+ .update(cx_b, |workspace, cx| {
+ workspace.open_path((worktree_id, "main.rs"), None, true, cx)
+ })
+ .await
+ .unwrap()
+ .downcast::<Editor>()
+ .unwrap();
+
+ cx_b.foreground().run_until_parked();
editor_b.update(cx_b, |editor, _| {
assert_eq!(
vec!["0".to_string(), "1".to_string()],
extract_hint_labels(editor),
+ "Client should get its first hints when opens an editor"
+ );
+ let inlay_cache = editor.inlay_hint_cache();
+ assert_eq!(
+ inlay_cache.allowed_hint_kinds, allowed_hint_kinds,
+ "Cache should use editor settings to get the allowed hint kinds"
+ );
+ assert_eq!(
+ inlay_cache.version, edits_made,
+ "Client editor should track its own inlay cache history, which should be incremented after every cache/view change"
+ );
+ });
+
+ editor_b.update(cx_b, |editor, cx| {
+ editor.change_selections(None, cx, |s| s.select_ranges([13..13].clone()));
+ editor.handle_input(":", cx);
+ cx.focus(&editor_b);
+ edits_made += 1;
+ });
+ cx_a.foreground().run_until_parked();
+ cx_b.foreground().run_until_parked();
+ editor_a.update(cx_a, |editor, _| {
+ assert_eq!(
+ vec!["0".to_string(), "1".to_string(), "2".to_string()],
+ extract_hint_labels(editor),
+ "Host should get hints from the 1st edit and 1st LSP query"
+ );
+ let inlay_cache = editor.inlay_hint_cache();
+ assert_eq!(
+ inlay_cache.allowed_hint_kinds, allowed_hint_kinds,
+ "Inlay kinds settings never change during the test"
+ );
+ assert_eq!(inlay_cache.version, edits_made);
+ });
+ editor_b.update(cx_b, |editor, _| {
+ assert_eq!(
+ vec!["0".to_string(), "1".to_string(), "2".to_string(), "3".to_string()],
+ extract_hint_labels(editor),
"Guest should get hints the 1st edit and 2nd LSP query"
);
let inlay_cache = editor.inlay_hint_cache();
@@ -8043,7 +8035,7 @@ async fn test_mutual_editor_inlay_hint_cache_update(
cx_b.foreground().run_until_parked();
editor_a.update(cx_a, |editor, _| {
assert_eq!(
- vec!["0".to_string(), "1".to_string(), "2".to_string()],
+ vec!["0".to_string(), "1".to_string(), "2".to_string(), "3".to_string(), "4".to_string()],
extract_hint_labels(editor),
"Host should get hints from 3rd edit, 5th LSP query: \
4th query was made by guest (but not applied) due to cache invalidation logic"
@@ -8061,7 +8053,9 @@ async fn test_mutual_editor_inlay_hint_cache_update(
"0".to_string(),
"1".to_string(),
"2".to_string(),
- "3".to_string()
+ "3".to_string(),
+ "4".to_string(),
+ "5".to_string(),
],
extract_hint_labels(editor),
"Guest should get hints from 3rd edit, 6th LSP query"
@@ -8091,7 +8085,9 @@ async fn test_mutual_editor_inlay_hint_cache_update(
"1".to_string(),
"2".to_string(),
"3".to_string(),
- "4".to_string()
+ "4".to_string(),
+ "5".to_string(),
+ "6".to_string(),
],
extract_hint_labels(editor),
"Host should react to /refresh LSP request and get new hints from 7th LSP query"
@@ -8108,7 +8104,16 @@ async fn test_mutual_editor_inlay_hint_cache_update(
});
editor_b.update(cx_b, |editor, _| {
assert_eq!(
- vec!["0".to_string(), "1".to_string(), "2".to_string(), "3".to_string(), "4".to_string(), "5".to_string()],
+ vec![
+ "0".to_string(),
+ "1".to_string(),
+ "2".to_string(),
+ "3".to_string(),
+ "4".to_string(),
+ "5".to_string(),
+ "6".to_string(),
+ "7".to_string(),
+ ],
extract_hint_labels(editor),
"Guest should get a /refresh LSP request propagated by host and get new hints from 8th LSP query"
);
@@ -8120,7 +8125,7 @@ async fn test_mutual_editor_inlay_hint_cache_update(
assert_eq!(
inlay_cache.version,
edits_made,
- "Gues should accepted all edits and bump its cache version every time"
+ "Guest should accepted all edits and bump its cache version every time"
);
});
}
@@ -8148,3 +8153,17 @@ fn room_participants(room: &ModelHandle<Room>, cx: &mut TestAppContext) -> RoomP
RoomParticipants { remote, pending }
})
}
+
+fn extract_hint_labels(editor: &Editor) -> Vec<String> {
+ let mut labels = Vec::new();
+ for (_, excerpt_hints) in &editor.inlay_hint_cache().hints {
+ let excerpt_hints = excerpt_hints.read();
+ for (_, inlay) in excerpt_hints.hints.iter() {
+ match &inlay.label {
+ project::InlayHintLabel::String(s) => labels.push(s.to_string()),
+ _ => unreachable!(),
+ }
+ }
+ }
+ labels
+}
@@ -19,7 +19,8 @@ use crate::{
display_map::{DisplaySnapshot, ToDisplayPoint},
hover_popover::hide_hover,
persistence::DB,
- Anchor, DisplayPoint, Editor, EditorMode, Event, MultiBufferSnapshot, ToPoint,
+ Anchor, DisplayPoint, Editor, EditorMode, Event, InlayRefreshReason, MultiBufferSnapshot,
+ ToPoint,
};
use self::{
@@ -293,8 +294,19 @@ impl Editor {
self.scroll_manager.visible_line_count
}
- pub(crate) fn set_visible_line_count(&mut self, lines: f32) {
+ pub(crate) fn set_visible_line_count(&mut self, lines: f32, cx: &mut ViewContext<Self>) {
+ let opened_first_time = self.scroll_manager.visible_line_count.is_none();
self.scroll_manager.visible_line_count = Some(lines);
+ if opened_first_time {
+ cx.spawn(|editor, mut cx| async move {
+ editor
+ .update(&mut cx, |editor, cx| {
+ editor.refresh_inlays(InlayRefreshReason::NewLinesShown, cx)
+ })
+ .ok()
+ })
+ .detach()
+ }
}
pub fn set_scroll_position(&mut self, scroll_position: Vector2F, cx: &mut ViewContext<Self>) {
@@ -322,7 +334,7 @@ impl Editor {
);
if !self.is_singleton(cx) {
- self.refresh_inlays(crate::InlayRefreshReason::NewLinesShown, cx);
+ self.refresh_inlays(InlayRefreshReason::NewLinesShown, cx);
}
}