Properly discard tokens on language server stop (#48490)
Follow-up of https://github.com/zed-industries/zed/pull/46356 Release Notes: - N/A
This commit is contained in:
1 parent
723f683dda
commit
8bb69dcb14
2 files changed
+97
-16
No files matched your search
@@ -2163,7 +2163,7 @@ impl Editor {
|
||||
}
|
||||
editor.registered_buffers.clear();
|
||||
editor.register_visible_buffers(cx);
|
||||
editor.update_semantic_tokens(None, None, cx);
|
||||
editor.refresh_semantic_token_highlights(cx);
|
||||
editor.refresh_inlay_hints(InlayHintRefreshReason::ServerRemoved, cx);
|
||||
}
|
||||
project::Event::LanguageServerAdded(..) => {
|
||||
|
||||
@@ -209,6 +209,9 @@ impl Editor {
|
||||
tokens
|
||||
},
|
||||
Ok(BufferSemanticTokens { tokens: None }) => {
|
||||
editor.display_map.update(cx, |display_map, _| {
|
||||
display_map.invalidate_semantic_highlights(buffer_id);
|
||||
});
|
||||
continue;
|
||||
},
|
||||
Err(e) => {
|
||||
@@ -458,14 +461,14 @@ mod tests {
|
||||
lsp::SemanticTokensOptions {
|
||||
legend: lsp::SemanticTokensLegend {
|
||||
token_types: vec!["function".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
},
|
||||
full: Some(lsp::SemanticTokensFullOptions::Delta { delta: None }),
|
||||
..Default::default()
|
||||
..lsp::SemanticTokensOptions::default()
|
||||
},
|
||||
),
|
||||
),
|
||||
..Default::default()
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
@@ -536,14 +539,14 @@ mod tests {
|
||||
lsp::SemanticTokensOptions {
|
||||
legend: lsp::SemanticTokensLegend {
|
||||
token_types: vec!["function".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
},
|
||||
full: Some(lsp::SemanticTokensFullOptions::Delta { delta: Some(true) }),
|
||||
..Default::default()
|
||||
..lsp::SemanticTokensOptions::default()
|
||||
},
|
||||
),
|
||||
),
|
||||
..Default::default()
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
@@ -612,14 +615,14 @@ mod tests {
|
||||
lsp::SemanticTokensOptions {
|
||||
legend: lsp::SemanticTokensLegend {
|
||||
token_types: vec!["function".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
},
|
||||
full: Some(lsp::SemanticTokensFullOptions::Delta { delta: Some(true) }),
|
||||
..Default::default()
|
||||
..lsp::SemanticTokensOptions::default()
|
||||
},
|
||||
),
|
||||
),
|
||||
..Default::default()
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
@@ -659,7 +662,7 @@ mod tests {
|
||||
async move {
|
||||
Ok(Some(lsp::SemanticTokensFullDeltaResult::TokensDelta(
|
||||
lsp::SemanticTokensDelta {
|
||||
edits: vec![],
|
||||
edits: Vec::new(),
|
||||
result_id: Some("b".into()),
|
||||
},
|
||||
)))
|
||||
@@ -716,11 +719,11 @@ mod tests {
|
||||
// We have 2 language servers for TOML in this test.
|
||||
let toml_legend_1 = lsp::SemanticTokensLegend {
|
||||
token_types: vec!["property".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
};
|
||||
let toml_legend_2 = lsp::SemanticTokensLegend {
|
||||
token_types: vec!["number".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
};
|
||||
|
||||
let app_state = cx.update(workspace::AppState::test);
|
||||
@@ -954,11 +957,11 @@ mod tests {
|
||||
|
||||
let toml_legend = lsp::SemanticTokensLegend {
|
||||
token_types: vec!["property".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
};
|
||||
let rust_legend = lsp::SemanticTokensLegend {
|
||||
token_types: vec!["constant".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
};
|
||||
|
||||
let app_state = cx.update(workspace::AppState::test);
|
||||
@@ -1221,7 +1224,7 @@ mod tests {
|
||||
|
||||
let toml_legend = lsp::SemanticTokensLegend {
|
||||
token_types: vec!["property".into()],
|
||||
token_modifiers: vec![],
|
||||
token_modifiers: Vec::new(),
|
||||
};
|
||||
|
||||
let app_state = cx.update(workspace::AppState::test);
|
||||
@@ -1806,6 +1809,84 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_stopping_language_server_clears_semantic_tokens(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
update_test_language_settings(cx, |language_settings| {
|
||||
language_settings.languages.0.insert(
|
||||
"Rust".into(),
|
||||
LanguageSettingsContent {
|
||||
semantic_tokens: Some(SemanticTokens::Full),
|
||||
..LanguageSettingsContent::default()
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
let mut cx = EditorLspTestContext::new_rust(
|
||||
lsp::ServerCapabilities {
|
||||
semantic_tokens_provider: Some(
|
||||
lsp::SemanticTokensServerCapabilities::SemanticTokensOptions(
|
||||
lsp::SemanticTokensOptions {
|
||||
legend: lsp::SemanticTokensLegend {
|
||||
token_types: vec!["function".into()],
|
||||
token_modifiers: Vec::new(),
|
||||
},
|
||||
full: Some(lsp::SemanticTokensFullOptions::Delta { delta: None }),
|
||||
..lsp::SemanticTokensOptions::default()
|
||||
},
|
||||
),
|
||||
),
|
||||
..lsp::ServerCapabilities::default()
|
||||
},
|
||||
cx,
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut full_request = cx
|
||||
.set_request_handler::<lsp::request::SemanticTokensFullRequest, _, _>(
|
||||
move |_, _, _| async move {
|
||||
Ok(Some(lsp::SemanticTokensResult::Tokens(
|
||||
lsp::SemanticTokens {
|
||||
data: vec![
|
||||
0, // delta_line
|
||||
3, // delta_start
|
||||
4, // length
|
||||
0, // token_type
|
||||
0, // token_modifiers_bitset
|
||||
],
|
||||
result_id: None,
|
||||
},
|
||||
)))
|
||||
},
|
||||
);
|
||||
|
||||
cx.set_state("ˇfn main() {}");
|
||||
assert!(full_request.next().await.is_some());
|
||||
cx.run_until_parked();
|
||||
|
||||
assert_eq!(
|
||||
extract_semantic_highlights(&cx.editor, &cx),
|
||||
vec![MultiBufferOffset(3)..MultiBufferOffset(7)],
|
||||
"Semantic tokens should be present before stopping the server"
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, _, cx| {
|
||||
let buffers = editor.buffer.read(cx).all_buffers().into_iter().collect();
|
||||
editor.project.as_ref().unwrap().update(cx, |project, cx| {
|
||||
project.stop_language_servers_for_buffers(buffers, HashSet::default(), cx);
|
||||
})
|
||||
});
|
||||
cx.executor().advance_clock(Duration::from_millis(200));
|
||||
cx.run_until_parked();
|
||||
|
||||
assert_eq!(
|
||||
extract_semantic_highlights(&cx.editor, &cx),
|
||||
Vec::new(),
|
||||
"Semantic tokens should be cleared after stopping the server"
|
||||
);
|
||||
}
|
||||
|
||||
fn extract_semantic_highlight_styles(
|
||||
editor: &Entity<Editor>,
|
||||
cx: &TestAppContext,
|
||||
|
||||
Reference in new issue
Block a user