From e1aa73ef40b8902b2cbdd8272978fcc1c47cf3c7 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Wed, 21 Dec 2022 18:54:49 +0330 Subject: [PATCH] Disable inlay hint location links on vscode < 1.76 --- crates/ide/src/inlay_hints.rs | 14 +++- crates/ide/src/inlay_hints/bind_pat.rs | 5 +- crates/ide/src/inlay_hints/chaining.rs | 76 +++++++++++++++++++-- crates/ide/src/inlay_hints/closing_brace.rs | 5 +- crates/ide/src/static_index.rs | 1 + crates/rust-analyzer/src/bin/main.rs | 2 + crates/rust-analyzer/src/config.rs | 18 ++++- docs/user/generated_config.adoc | 5 ++ editors/code/package.json | 5 ++ 9 files changed, 121 insertions(+), 10 deletions(-) diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 8163697fbfc..9aef78143d6 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -27,6 +27,7 @@ mod bind_pat; #[derive(Clone, Debug, PartialEq, Eq)] pub struct InlayHintsConfig { + pub location_links: bool, pub render_colons: bool, pub type_hints: bool, pub parameter_hints: bool, @@ -182,6 +183,7 @@ struct InlayHintLabelBuilder<'a> { db: &'a RootDatabase, result: InlayHintLabel, last_part: String, + location_link_enabled: bool, location: Option, } @@ -193,6 +195,9 @@ impl fmt::Write for InlayHintLabelBuilder<'_> { impl HirWrite for InlayHintLabelBuilder<'_> { fn start_location_link(&mut self, def: ModuleDefId) { + if !self.location_link_enabled { + return; + } if self.location.is_some() { never!("location link is already started"); } @@ -204,6 +209,9 @@ impl HirWrite for InlayHintLabelBuilder<'_> { } fn end_location_link(&mut self) { + if !self.location_link_enabled { + return; + } self.make_new_part(); } } @@ -260,6 +268,7 @@ fn label_of_ty( db: sema.db, last_part: String::new(), location: None, + location_link_enabled: config.location_links, result: InlayHintLabel::default(), }; rec(sema, &famous_defs, config.max_length, ty, &mut label_builder); @@ -416,6 +425,7 @@ mod tests { use super::ClosureReturnTypeHints; pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig { + location_links: false, render_colons: false, type_hints: false, parameter_hints: false, @@ -430,6 +440,8 @@ mod tests { max_length: None, closing_brace_hints_min_lines: None, }; + pub(super) const DISABLED_CONFIG_WITH_LINKS: InlayHintsConfig = + InlayHintsConfig { location_links: true, ..DISABLED_CONFIG }; pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig { type_hints: true, parameter_hints: true, @@ -437,7 +449,7 @@ mod tests { closure_return_type_hints: ClosureReturnTypeHints::WithBlock, binding_mode_hints: true, lifetime_elision_hints: LifetimeElisionHints::Always, - ..DISABLED_CONFIG + ..DISABLED_CONFIG_WITH_LINKS }; #[track_caller] diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs index c9f787e0748..7766d497918 100644 --- a/crates/ide/src/inlay_hints/bind_pat.rs +++ b/crates/ide/src/inlay_hints/bind_pat.rs @@ -194,7 +194,8 @@ mod tests { use crate::{fixture, inlay_hints::InlayHintsConfig}; use crate::inlay_hints::tests::{ - check, check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG, + check, check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS, + TEST_CONFIG, }; use crate::ClosureReturnTypeHints; @@ -290,7 +291,7 @@ fn main() { fn iterator_hint_regression_issue_12674() { // Ensure we don't crash while solving the projection type of iterators. check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, r#" //- minicore: iterators struct S(T); diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs index c9aabcbb044..efeb2b79255 100644 --- a/crates/ide/src/inlay_hints/chaining.rs +++ b/crates/ide/src/inlay_hints/chaining.rs @@ -74,7 +74,10 @@ mod tests { use expect_test::expect; use crate::{ - inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG}, + inlay_hints::tests::{ + check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS, + TEST_CONFIG, + }, InlayHintsConfig, }; @@ -86,7 +89,11 @@ mod tests { #[test] fn chaining_hints_ignore_comments() { check_expect( - InlayHintsConfig { type_hints: false, chaining_hints: true, ..DISABLED_CONFIG }, + InlayHintsConfig { + type_hints: false, + chaining_hints: true, + ..DISABLED_CONFIG_WITH_LINKS + }, r#" struct A(B); impl A { fn into_b(self) -> B { self.0 } } @@ -179,10 +186,69 @@ fn main() { } #[test] - fn struct_access_chaining_hints() { + fn disabled_location_links() { check_expect( InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, r#" + struct A { pub b: B } + struct B { pub c: C } + struct C(pub bool); + struct D; + + impl D { + fn foo(&self) -> i32 { 42 } + } + + fn main() { + let x = A { b: B { c: C(true) } } + .b + .c + .0; + let x = D + .foo(); + }"#, + expect![[r#" + [ + InlayHint { + range: 143..190, + kind: ChainingHint, + label: [ + "C", + ], + tooltip: Some( + HoverRanged( + FileId( + 0, + ), + 143..190, + ), + ), + }, + InlayHint { + range: 143..179, + kind: ChainingHint, + label: [ + "B", + ], + tooltip: Some( + HoverRanged( + FileId( + 0, + ), + 143..179, + ), + ), + }, + ] + "#]], + ); + } + + #[test] + fn struct_access_chaining_hints() { + check_expect( + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, + r#" struct A { pub b: B } struct B { pub c: C } struct C(pub bool); @@ -264,7 +330,7 @@ fn main() { #[test] fn generic_chaining_hints() { check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, r#" struct A(T); struct B(T); @@ -372,7 +438,7 @@ fn main() { #[test] fn shorten_iterator_chaining_hints() { check_expect( - InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, + InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS }, r#" //- minicore: iterators use core::iter; diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs index 57605b392a8..e340c64c54b 100644 --- a/crates/ide/src/inlay_hints/closing_brace.rs +++ b/crates/ide/src/inlay_hints/closing_brace.rs @@ -109,7 +109,10 @@ pub(super) fn hints( return None; } - let linked_location = name_range.map(|range| FileRange { file_id, range }); + let linked_location = config + .location_links + .then(|| name_range.map(|range| FileRange { file_id, range })) + .flatten(); acc.push(InlayHint { range: closing_token.text_range(), kind: InlayKind::ClosingBraceHint, diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index 2380cf7381c..42b5951c842 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -106,6 +106,7 @@ impl StaticIndex<'_> { .analysis .inlay_hints( &InlayHintsConfig { + location_links: true, render_colons: true, type_hints: true, parameter_hints: true, diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 7bf595d2a45..ec5053e991d 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -183,6 +183,8 @@ fn run_server() -> Result<()> { } } + config.client_specific_adjustments(&initialize_params.client_info); + let server_capabilities = rust_analyzer::server_capabilities(&config); let initialize_result = lsp_types::InitializeResult { diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 835b37c98e2..0bcc91eb411 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -20,7 +20,7 @@ use ide_db::{ SnippetCap, }; use itertools::Itertools; -use lsp_types::{ClientCapabilities, MarkupKind}; +use lsp_types::{ClientCapabilities, ClientInfo, MarkupKind}; use project_model::{ CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource, UnsetTestCrates, @@ -333,6 +333,8 @@ config_data! { inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"", /// Whether to prefer using parameter names as the name for elided lifetime hints if possible. inlayHints_lifetimeElisionHints_useParameterNames: bool = "false", + /// Whether to use location links for parts of type mentioned in inlay hints. + inlayHints_locationLinks: bool = "true", /// Maximum length for inlay hints. Set to null to have an unlimited length. inlayHints_maxLength: Option = "25", /// Whether to show function parameter name inlay hints at the call @@ -714,6 +716,19 @@ impl Config { } } + pub fn client_specific_adjustments(&mut self, client_info: &Option) { + // FIXME: remove this when we drop support for vscode 1.65 and below + if let Some(client) = client_info { + if client.name.contains("Code") || client.name.contains("Codium") { + if let Some(version) = &client.version { + if version.as_str() < "1.76" { + self.data.inlayHints_locationLinks = false; + } + } + } + } + } + pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> { tracing::info!("updating config from JSON: {:#}", json); if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { @@ -1196,6 +1211,7 @@ impl Config { pub fn inlay_hints(&self) -> InlayHintsConfig { InlayHintsConfig { + location_links: self.data.inlayHints_locationLinks, render_colons: self.data.inlayHints_renderColons, type_hints: self.data.inlayHints_typeHints_enable, parameter_hints: self.data.inlayHints_parameterHints_enable, diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index db41c7bf109..47511aad0fe 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -469,6 +469,11 @@ Whether to show inlay type hints for elided lifetimes in function signatures. -- Whether to prefer using parameter names as the name for elided lifetime hints if possible. -- +[[rust-analyzer.inlayHints.locationLinks]]rust-analyzer.inlayHints.locationLinks (default: `true`):: ++ +-- +Whether to use location links for parts of type mentioned in inlay hints. +-- [[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`):: + -- diff --git a/editors/code/package.json b/editors/code/package.json index f9b0e28dadb..5b09ee6f7da 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -995,6 +995,11 @@ "default": false, "type": "boolean" }, + "rust-analyzer.inlayHints.locationLinks": { + "markdownDescription": "Whether to use location links for parts of type mentioned in inlay hints.", + "default": true, + "type": "boolean" + }, "rust-analyzer.inlayHints.maxLength": { "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.", "default": 25,