Disable inlay hint location links on vscode < 1.76

This commit is contained in:
hkalbasi 2022-12-21 18:54:49 +03:30
parent 801a2231bf
commit e1aa73ef40
9 changed files with 121 additions and 10 deletions

View file

@ -27,6 +27,7 @@ mod bind_pat;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct InlayHintsConfig { pub struct InlayHintsConfig {
pub location_links: bool,
pub render_colons: bool, pub render_colons: bool,
pub type_hints: bool, pub type_hints: bool,
pub parameter_hints: bool, pub parameter_hints: bool,
@ -182,6 +183,7 @@ struct InlayHintLabelBuilder<'a> {
db: &'a RootDatabase, db: &'a RootDatabase,
result: InlayHintLabel, result: InlayHintLabel,
last_part: String, last_part: String,
location_link_enabled: bool,
location: Option<FileRange>, location: Option<FileRange>,
} }
@ -193,6 +195,9 @@ impl fmt::Write for InlayHintLabelBuilder<'_> {
impl HirWrite for InlayHintLabelBuilder<'_> { impl HirWrite for InlayHintLabelBuilder<'_> {
fn start_location_link(&mut self, def: ModuleDefId) { fn start_location_link(&mut self, def: ModuleDefId) {
if !self.location_link_enabled {
return;
}
if self.location.is_some() { if self.location.is_some() {
never!("location link is already started"); never!("location link is already started");
} }
@ -204,6 +209,9 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
} }
fn end_location_link(&mut self) { fn end_location_link(&mut self) {
if !self.location_link_enabled {
return;
}
self.make_new_part(); self.make_new_part();
} }
} }
@ -260,6 +268,7 @@ fn label_of_ty(
db: sema.db, db: sema.db,
last_part: String::new(), last_part: String::new(),
location: None, location: None,
location_link_enabled: config.location_links,
result: InlayHintLabel::default(), result: InlayHintLabel::default(),
}; };
rec(sema, &famous_defs, config.max_length, ty, &mut label_builder); rec(sema, &famous_defs, config.max_length, ty, &mut label_builder);
@ -416,6 +425,7 @@ mod tests {
use super::ClosureReturnTypeHints; use super::ClosureReturnTypeHints;
pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig { pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
location_links: false,
render_colons: false, render_colons: false,
type_hints: false, type_hints: false,
parameter_hints: false, parameter_hints: false,
@ -430,6 +440,8 @@ mod tests {
max_length: None, max_length: None,
closing_brace_hints_min_lines: 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 { pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig {
type_hints: true, type_hints: true,
parameter_hints: true, parameter_hints: true,
@ -437,7 +449,7 @@ mod tests {
closure_return_type_hints: ClosureReturnTypeHints::WithBlock, closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
binding_mode_hints: true, binding_mode_hints: true,
lifetime_elision_hints: LifetimeElisionHints::Always, lifetime_elision_hints: LifetimeElisionHints::Always,
..DISABLED_CONFIG ..DISABLED_CONFIG_WITH_LINKS
}; };
#[track_caller] #[track_caller]

View file

@ -194,7 +194,8 @@ mod tests {
use crate::{fixture, inlay_hints::InlayHintsConfig}; use crate::{fixture, inlay_hints::InlayHintsConfig};
use crate::inlay_hints::tests::{ 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; use crate::ClosureReturnTypeHints;
@ -290,7 +291,7 @@ fn main() {
fn iterator_hint_regression_issue_12674() { fn iterator_hint_regression_issue_12674() {
// Ensure we don't crash while solving the projection type of iterators. // Ensure we don't crash while solving the projection type of iterators.
check_expect( check_expect(
InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
r#" r#"
//- minicore: iterators //- minicore: iterators
struct S<T>(T); struct S<T>(T);

View file

@ -74,7 +74,10 @@ mod tests {
use expect_test::expect; use expect_test::expect;
use crate::{ 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, InlayHintsConfig,
}; };
@ -86,7 +89,11 @@ mod tests {
#[test] #[test]
fn chaining_hints_ignore_comments() { fn chaining_hints_ignore_comments() {
check_expect( check_expect(
InlayHintsConfig { type_hints: false, chaining_hints: true, ..DISABLED_CONFIG }, InlayHintsConfig {
type_hints: false,
chaining_hints: true,
..DISABLED_CONFIG_WITH_LINKS
},
r#" r#"
struct A(B); struct A(B);
impl A { fn into_b(self) -> B { self.0 } } impl A { fn into_b(self) -> B { self.0 } }
@ -179,10 +186,69 @@ fn main() {
} }
#[test] #[test]
fn struct_access_chaining_hints() { fn disabled_location_links() {
check_expect( check_expect(
InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
r#" 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 A { pub b: B }
struct B { pub c: C } struct B { pub c: C }
struct C(pub bool); struct C(pub bool);
@ -264,7 +330,7 @@ fn main() {
#[test] #[test]
fn generic_chaining_hints() { fn generic_chaining_hints() {
check_expect( check_expect(
InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
r#" r#"
struct A<T>(T); struct A<T>(T);
struct B<T>(T); struct B<T>(T);
@ -372,7 +438,7 @@ fn main() {
#[test] #[test]
fn shorten_iterator_chaining_hints() { fn shorten_iterator_chaining_hints() {
check_expect( check_expect(
InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG }, InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
r#" r#"
//- minicore: iterators //- minicore: iterators
use core::iter; use core::iter;

View file

@ -109,7 +109,10 @@ pub(super) fn hints(
return None; 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 { acc.push(InlayHint {
range: closing_token.text_range(), range: closing_token.text_range(),
kind: InlayKind::ClosingBraceHint, kind: InlayKind::ClosingBraceHint,

View file

@ -106,6 +106,7 @@ impl StaticIndex<'_> {
.analysis .analysis
.inlay_hints( .inlay_hints(
&InlayHintsConfig { &InlayHintsConfig {
location_links: true,
render_colons: true, render_colons: true,
type_hints: true, type_hints: true,
parameter_hints: true, parameter_hints: true,

View file

@ -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 server_capabilities = rust_analyzer::server_capabilities(&config);
let initialize_result = lsp_types::InitializeResult { let initialize_result = lsp_types::InitializeResult {

View file

@ -20,7 +20,7 @@ use ide_db::{
SnippetCap, SnippetCap,
}; };
use itertools::Itertools; use itertools::Itertools;
use lsp_types::{ClientCapabilities, MarkupKind}; use lsp_types::{ClientCapabilities, ClientInfo, MarkupKind};
use project_model::{ use project_model::{
CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource, CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource,
UnsetTestCrates, UnsetTestCrates,
@ -333,6 +333,8 @@ config_data! {
inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"", inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
/// Whether to prefer using parameter names as the name for elided lifetime hints if possible. /// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
inlayHints_lifetimeElisionHints_useParameterNames: bool = "false", 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. /// Maximum length for inlay hints. Set to null to have an unlimited length.
inlayHints_maxLength: Option<usize> = "25", inlayHints_maxLength: Option<usize> = "25",
/// Whether to show function parameter name inlay hints at the call /// 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<ClientInfo>) {
// 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> { pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
tracing::info!("updating config from JSON: {:#}", json); tracing::info!("updating config from JSON: {:#}", json);
if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { 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 { pub fn inlay_hints(&self) -> InlayHintsConfig {
InlayHintsConfig { InlayHintsConfig {
location_links: self.data.inlayHints_locationLinks,
render_colons: self.data.inlayHints_renderColons, render_colons: self.data.inlayHints_renderColons,
type_hints: self.data.inlayHints_typeHints_enable, type_hints: self.data.inlayHints_typeHints_enable,
parameter_hints: self.data.inlayHints_parameterHints_enable, parameter_hints: self.data.inlayHints_parameterHints_enable,

View file

@ -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. 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`):: [[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`)::
+ +
-- --

View file

@ -995,6 +995,11 @@
"default": false, "default": false,
"type": "boolean" "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": { "rust-analyzer.inlayHints.maxLength": {
"markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.", "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.",
"default": 25, "default": 25,