mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
feat: add inlay hints for generic parameters
fixes #11091 By default, only hints for const generic parameters are shown.
This commit is contained in:
parent
a5b21ea0aa
commit
35b4957b80
10 changed files with 443 additions and 14 deletions
|
@ -29,6 +29,7 @@ mod closure_captures;
|
|||
mod closure_ret;
|
||||
mod discriminant;
|
||||
mod fn_lifetime_fn;
|
||||
mod generic_param;
|
||||
mod implicit_drop;
|
||||
mod implicit_static;
|
||||
mod param_name;
|
||||
|
@ -40,6 +41,7 @@ pub struct InlayHintsConfig {
|
|||
pub type_hints: bool,
|
||||
pub discriminant_hints: DiscriminantHints,
|
||||
pub parameter_hints: bool,
|
||||
pub generic_parameter_hints: GenericParameterHints,
|
||||
pub chaining_hints: bool,
|
||||
pub adjustment_hints: AdjustmentHints,
|
||||
pub adjustment_hints_mode: AdjustmentHintsMode,
|
||||
|
@ -94,6 +96,13 @@ pub enum DiscriminantHints {
|
|||
Fieldless,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct GenericParameterHints {
|
||||
pub type_hints: bool,
|
||||
pub lifetime_hints: bool,
|
||||
pub const_hints: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LifetimeElisionHints {
|
||||
Always,
|
||||
|
@ -127,6 +136,7 @@ pub enum InlayKind {
|
|||
GenericParamList,
|
||||
Lifetime,
|
||||
Parameter,
|
||||
GenericParameter,
|
||||
Type,
|
||||
Drop,
|
||||
RangeExclusive,
|
||||
|
@ -447,6 +457,7 @@ fn ty_to_text_edit(
|
|||
//
|
||||
// * types of local variables
|
||||
// * names of function arguments
|
||||
// * names of const generic parameters
|
||||
// * types of chained expressions
|
||||
//
|
||||
// Optionally, one can enable additional hints for
|
||||
|
@ -454,6 +465,7 @@ fn ty_to_text_edit(
|
|||
// * return types of closure expressions
|
||||
// * elided lifetimes
|
||||
// * compiler inserted reborrows
|
||||
// * names of generic type and lifetime parameters
|
||||
//
|
||||
// Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if
|
||||
// any of the
|
||||
|
@ -543,6 +555,9 @@ fn hints(
|
|||
node: SyntaxNode,
|
||||
) {
|
||||
closing_brace::hints(hints, sema, config, file_id, node.clone());
|
||||
if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
|
||||
generic_param::hints(hints, sema, config, any_has_generic_args);
|
||||
}
|
||||
match_ast! {
|
||||
match node {
|
||||
ast::Expr(expr) => {
|
||||
|
@ -645,13 +660,18 @@ mod tests {
|
|||
use crate::DiscriminantHints;
|
||||
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
|
||||
|
||||
use super::{ClosureReturnTypeHints, InlayFieldsToResolve};
|
||||
use super::{ClosureReturnTypeHints, GenericParameterHints, InlayFieldsToResolve};
|
||||
|
||||
pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
|
||||
discriminant_hints: DiscriminantHints::Never,
|
||||
render_colons: false,
|
||||
type_hints: false,
|
||||
parameter_hints: false,
|
||||
generic_parameter_hints: GenericParameterHints {
|
||||
type_hints: false,
|
||||
lifetime_hints: false,
|
||||
const_hints: false,
|
||||
},
|
||||
chaining_hints: false,
|
||||
lifetime_elision_hints: LifetimeElisionHints::Never,
|
||||
closure_return_type_hints: ClosureReturnTypeHints::Never,
|
||||
|
|
315
crates/ide/src/inlay_hints/generic_param.rs
Normal file
315
crates/ide/src/inlay_hints/generic_param.rs
Normal file
|
@ -0,0 +1,315 @@
|
|||
//! Implementation of inlay hints for generic parameters.
|
||||
use ide_db::{active_parameter::generic_def_for_node, RootDatabase};
|
||||
use syntax::{
|
||||
ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName},
|
||||
AstNode,
|
||||
};
|
||||
|
||||
use crate::{inlay_hints::GenericParameterHints, InlayHint, InlayHintsConfig, InlayKind};
|
||||
|
||||
use super::param_name::{is_argument_similar_to_param_name, render_label};
|
||||
|
||||
pub(crate) fn hints(
|
||||
acc: &mut Vec<InlayHint>,
|
||||
sema: &hir::Semantics<'_, RootDatabase>,
|
||||
config: &InlayHintsConfig,
|
||||
node: AnyHasGenericArgs,
|
||||
) -> Option<()> {
|
||||
let GenericParameterHints { type_hints, lifetime_hints, const_hints } =
|
||||
config.generic_parameter_hints;
|
||||
if !(type_hints || lifetime_hints || const_hints) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let generic_arg_list = node.generic_arg_list()?;
|
||||
|
||||
let (generic_def, _, _, _) =
|
||||
generic_def_for_node(sema, &generic_arg_list, &node.syntax().first_token()?)?;
|
||||
|
||||
let mut args = generic_arg_list.generic_args().peekable();
|
||||
let start_with_lifetime = matches!(args.peek()?, ast::GenericArg::LifetimeArg(_));
|
||||
let params = generic_def.params(sema.db).into_iter().filter(|p| {
|
||||
if let hir::GenericParam::TypeParam(it) = p {
|
||||
if it.is_implicit(sema.db) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if !start_with_lifetime {
|
||||
return !matches!(p, hir::GenericParam::LifetimeParam(_));
|
||||
}
|
||||
true
|
||||
});
|
||||
|
||||
let hints = params.zip(args).filter_map(|(param, arg)| {
|
||||
if matches!(arg, ast::GenericArg::AssocTypeArg(_)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let name = param.name(sema.db);
|
||||
let param_name = name.as_str()?;
|
||||
|
||||
let should_hide = {
|
||||
let argument = get_string_representation(&arg)?;
|
||||
is_argument_similar_to_param_name(&argument, param_name)
|
||||
};
|
||||
|
||||
if should_hide {
|
||||
return None;
|
||||
}
|
||||
|
||||
let range = sema.original_range_opt(arg.syntax())?.range;
|
||||
|
||||
let source_syntax = match param {
|
||||
hir::GenericParam::TypeParam(it) => {
|
||||
if !type_hints || !matches!(arg, ast::GenericArg::TypeArg(_)) {
|
||||
return None;
|
||||
}
|
||||
sema.source(it.merge())?.value.syntax().clone()
|
||||
}
|
||||
hir::GenericParam::ConstParam(it) => {
|
||||
if !const_hints || !matches!(arg, ast::GenericArg::ConstArg(_)) {
|
||||
return None;
|
||||
}
|
||||
let syntax = sema.source(it.merge())?.value.syntax().clone();
|
||||
let const_param = ast::ConstParam::cast(syntax)?;
|
||||
const_param.name()?.syntax().clone()
|
||||
}
|
||||
hir::GenericParam::LifetimeParam(it) => {
|
||||
if !lifetime_hints || !matches!(arg, ast::GenericArg::LifetimeArg(_)) {
|
||||
return None;
|
||||
}
|
||||
sema.source(it)?.value.syntax().clone()
|
||||
}
|
||||
};
|
||||
let linked_location = sema.original_range_opt(&source_syntax);
|
||||
let label = render_label(param_name, config, linked_location);
|
||||
|
||||
Some(InlayHint {
|
||||
range,
|
||||
position: crate::InlayHintPosition::Before,
|
||||
pad_left: false,
|
||||
pad_right: true,
|
||||
kind: InlayKind::GenericParameter,
|
||||
label,
|
||||
text_edit: None,
|
||||
})
|
||||
});
|
||||
|
||||
acc.extend(hints);
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn get_string_representation(arg: &ast::GenericArg) -> Option<String> {
|
||||
return match arg {
|
||||
ast::GenericArg::AssocTypeArg(_) => None,
|
||||
ast::GenericArg::ConstArg(const_arg) => Some(const_arg.to_string()),
|
||||
ast::GenericArg::LifetimeArg(lifetime_arg) => {
|
||||
let lifetime = lifetime_arg.lifetime()?;
|
||||
Some(lifetime.to_string())
|
||||
}
|
||||
ast::GenericArg::TypeArg(type_arg) => {
|
||||
let ty = type_arg.ty()?;
|
||||
Some(
|
||||
type_path_segment(&ty)
|
||||
.map_or_else(|| type_arg.to_string(), |segment| segment.to_string()),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
fn type_path_segment(ty: &ast::Type) -> Option<ast::PathSegment> {
|
||||
match ty {
|
||||
ast::Type::ArrayType(it) => type_path_segment(&it.ty()?),
|
||||
ast::Type::ForType(it) => type_path_segment(&it.ty()?),
|
||||
ast::Type::ParenType(it) => type_path_segment(&it.ty()?),
|
||||
ast::Type::PathType(path_type) => path_type.path()?.segment(),
|
||||
ast::Type::PtrType(it) => type_path_segment(&it.ty()?),
|
||||
ast::Type::RefType(it) => type_path_segment(&it.ty()?),
|
||||
ast::Type::SliceType(it) => type_path_segment(&it.ty()?),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
inlay_hints::{
|
||||
tests::{check_with_config, DISABLED_CONFIG},
|
||||
GenericParameterHints,
|
||||
},
|
||||
InlayHintsConfig,
|
||||
};
|
||||
|
||||
#[track_caller]
|
||||
fn generic_param_name_hints_always(ra_fixture: &str) {
|
||||
check_with_config(
|
||||
InlayHintsConfig {
|
||||
generic_parameter_hints: GenericParameterHints {
|
||||
type_hints: true,
|
||||
lifetime_hints: true,
|
||||
const_hints: true,
|
||||
},
|
||||
..DISABLED_CONFIG
|
||||
},
|
||||
ra_fixture,
|
||||
);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn generic_param_name_hints_const_only(ra_fixture: &str) {
|
||||
check_with_config(
|
||||
InlayHintsConfig {
|
||||
generic_parameter_hints: GenericParameterHints {
|
||||
type_hints: false,
|
||||
lifetime_hints: false,
|
||||
const_hints: true,
|
||||
},
|
||||
..DISABLED_CONFIG
|
||||
},
|
||||
ra_fixture,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_only() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<X, Y> {
|
||||
x: X,
|
||||
y: Y,
|
||||
}
|
||||
|
||||
fn foo(a: A<usize, u32>) {}
|
||||
//^^^^^ X ^^^ Y
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lifetime_and_type() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<'a, X> {
|
||||
x: &'a X
|
||||
}
|
||||
|
||||
fn foo<'b>(a: A<'b, u32>) {}
|
||||
//^^ 'a^^^ X
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn omit_lifetime() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<'a, X> {
|
||||
x: &'a X
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let x: i32 = 1;
|
||||
let a: A<i32> = A { x: &x };
|
||||
// ^^^ X
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn const_only() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<const X: usize, const Y: usize> {};
|
||||
|
||||
fn foo(a: A<12, 2>) {}
|
||||
//^^ X^ Y
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lifetime_and_type_and_const() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<'a, X, const LEN: usize> {
|
||||
x: &'a [X; LEN],
|
||||
}
|
||||
|
||||
fn foo<'b>(a: A<
|
||||
'b,
|
||||
// ^^ 'a
|
||||
u32,
|
||||
// ^^^ X
|
||||
3
|
||||
// ^ LEN
|
||||
>) {}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn const_only_config() {
|
||||
generic_param_name_hints_const_only(
|
||||
r#"
|
||||
struct A<'a, X, const LEN: usize> {
|
||||
x: &'a [X; LEN],
|
||||
}
|
||||
|
||||
fn foo<'b>(a: A<
|
||||
'b,
|
||||
u32,
|
||||
3
|
||||
// ^ LEN
|
||||
>) {}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assoc_type() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
trait Trait<T> {
|
||||
type Assoc1;
|
||||
type Assoc2;
|
||||
}
|
||||
|
||||
fn foo() -> impl Trait<i32, Assoc1 = u32, Assoc2 = u32> {}
|
||||
// ^^^ T
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_similar() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<'a, X, const N: usize> {
|
||||
x: &'a [X; N],
|
||||
}
|
||||
|
||||
const N: usize = 3;
|
||||
|
||||
mod m {
|
||||
type X = u32;
|
||||
}
|
||||
|
||||
fn foo<'a>(a: A<'a, m::X, N>) {}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mismatching_args() {
|
||||
generic_param_name_hints_always(
|
||||
r#"
|
||||
struct A<X, const N: usize> {
|
||||
x: [X; N]
|
||||
}
|
||||
|
||||
type InvalidType = A<3, i32>;
|
||||
"#,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
//! fn max(x: i32, y: i32) -> i32 { x + y }
|
||||
//! _ = max(/*x*/4, /*y*/4);
|
||||
//! ```
|
||||
use std::fmt::Display;
|
||||
|
||||
use either::Either;
|
||||
use hir::{Callable, Semantics};
|
||||
use ide_db::{base_db::FileRange, RootDatabase};
|
||||
|
@ -46,9 +48,7 @@ pub(super) fn hints(
|
|||
.map(|(param, param_name, _, FileRange { range, .. })| {
|
||||
let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax()));
|
||||
|
||||
let colon = if config.render_colons { ":" } else { "" };
|
||||
let label =
|
||||
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location);
|
||||
let label = render_label(¶m_name, config, linked_location);
|
||||
InlayHint {
|
||||
range,
|
||||
kind: InlayKind::Parameter,
|
||||
|
@ -64,6 +64,16 @@ pub(super) fn hints(
|
|||
Some(())
|
||||
}
|
||||
|
||||
pub(super) fn render_label(
|
||||
param_name: impl Display,
|
||||
config: &InlayHintsConfig,
|
||||
linked_location: Option<FileRange>,
|
||||
) -> InlayHintLabel {
|
||||
let colon = if config.render_colons { ":" } else { "" };
|
||||
|
||||
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location)
|
||||
}
|
||||
|
||||
fn get_callable(
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
expr: &ast::Expr,
|
||||
|
@ -113,7 +123,7 @@ fn should_hide_param_name_hint(
|
|||
};
|
||||
let fn_name = fn_name.as_deref();
|
||||
is_param_name_suffix_of_fn_name(param_name, callable, fn_name)
|
||||
|| is_argument_similar_to_param_name(argument, param_name)
|
||||
|| is_argument_expr_similar_to_param_name(argument, param_name)
|
||||
|| param_name.starts_with("ra_fixture")
|
||||
|| (callable.n_params() == 1 && is_obvious_param(param_name))
|
||||
|| is_adt_constructor_similar_to_param_name(sema, argument, param_name)
|
||||
|
@ -143,14 +153,17 @@ fn is_param_name_suffix_of_fn_name(
|
|||
}
|
||||
}
|
||||
|
||||
fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool {
|
||||
// check whether param_name and argument are the same or
|
||||
// whether param_name is a prefix/suffix of argument(split at `_`)
|
||||
fn is_argument_expr_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool {
|
||||
let argument = match get_string_representation(argument) {
|
||||
Some(argument) => argument,
|
||||
None => return false,
|
||||
};
|
||||
is_argument_similar_to_param_name(&argument, param_name)
|
||||
}
|
||||
|
||||
/// Check whether param_name and argument are the same or
|
||||
/// whether param_name is a prefix/suffix of argument(split at `_`).
|
||||
pub(super) fn is_argument_similar_to_param_name(argument: &str, param_name: &str) -> bool {
|
||||
// std is honestly too panic happy...
|
||||
let str_split_at = |str: &str, at| str.is_char_boundary(at).then(|| argument.split_at(at));
|
||||
|
||||
|
|
|
@ -89,8 +89,8 @@ pub use crate::{
|
|||
},
|
||||
inlay_hints::{
|
||||
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
|
||||
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintPosition,
|
||||
InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
|
||||
GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
|
||||
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
|
||||
},
|
||||
join_lines::JoinLinesConfig,
|
||||
markup::Markup,
|
||||
|
|
|
@ -131,6 +131,11 @@ impl StaticIndex<'_> {
|
|||
discriminant_hints: crate::DiscriminantHints::Fieldless,
|
||||
type_hints: true,
|
||||
parameter_hints: true,
|
||||
generic_parameter_hints: crate::GenericParameterHints {
|
||||
type_hints: false,
|
||||
lifetime_hints: false,
|
||||
const_hints: true,
|
||||
},
|
||||
chaining_hints: true,
|
||||
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
|
||||
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
|
||||
|
|
|
@ -1008,6 +1008,11 @@ impl flags::AnalysisStats {
|
|||
type_hints: true,
|
||||
discriminant_hints: ide::DiscriminantHints::Always,
|
||||
parameter_hints: true,
|
||||
generic_parameter_hints: ide::GenericParameterHints {
|
||||
type_hints: true,
|
||||
lifetime_hints: true,
|
||||
const_hints: true,
|
||||
},
|
||||
chaining_hints: true,
|
||||
adjustment_hints: ide::AdjustmentHints::Always,
|
||||
adjustment_hints_mode: ide::AdjustmentHintsMode::Postfix,
|
||||
|
|
|
@ -10,9 +10,9 @@ use dirs::config_dir;
|
|||
use flycheck::{CargoOptions, FlycheckConfig};
|
||||
use ide::{
|
||||
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
|
||||
HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve,
|
||||
InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
|
||||
Snippet, SnippetScope, SourceRootId,
|
||||
GenericParameterHints, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat,
|
||||
InlayFieldsToResolve, InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig,
|
||||
MemoryLayoutHoverRenderKind, Snippet, SnippetScope, SourceRootId,
|
||||
};
|
||||
use ide_db::{
|
||||
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
|
||||
|
@ -509,6 +509,12 @@ config_data! {
|
|||
inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = false,
|
||||
/// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
|
||||
inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = AdjustmentHintsModeDef::Prefix,
|
||||
/// Whether to show const generic parameter name inlay hints.
|
||||
inlayHints_genericParameterHints_const_enable: bool= false,
|
||||
/// Whether to show generic lifetime parameter name inlay hints.
|
||||
inlayHints_genericParameterHints_lifetime_enable: bool = true,
|
||||
/// Whether to show generic type parameter name inlay hints.
|
||||
inlayHints_genericParameterHints_type_enable: bool = false,
|
||||
/// Whether to show implicit drop hints.
|
||||
inlayHints_implicitDrops_enable: bool = false,
|
||||
/// Whether to show inlay type hints for elided lifetimes in function signatures.
|
||||
|
@ -1391,6 +1397,11 @@ impl Config {
|
|||
render_colons: self.inlayHints_renderColons().to_owned(),
|
||||
type_hints: self.inlayHints_typeHints_enable().to_owned(),
|
||||
parameter_hints: self.inlayHints_parameterHints_enable().to_owned(),
|
||||
generic_parameter_hints: GenericParameterHints {
|
||||
type_hints: self.inlayHints_genericParameterHints_type_enable().to_owned(),
|
||||
lifetime_hints: self.inlayHints_genericParameterHints_lifetime_enable().to_owned(),
|
||||
const_hints: self.inlayHints_genericParameterHints_const_enable().to_owned(),
|
||||
},
|
||||
chaining_hints: self.inlayHints_chainingHints_enable().to_owned(),
|
||||
discriminant_hints: match self.inlayHints_discriminantHints_enable() {
|
||||
DiscriminantHintsDef::Always => ide::DiscriminantHints::Always,
|
||||
|
@ -2874,6 +2885,19 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
|
|||
"Only show discriminant hints on fieldless enum variants."
|
||||
]
|
||||
},
|
||||
"GenericParameterHintsDef" => set! {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"always",
|
||||
"never",
|
||||
"const_only"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Always show generic parameter hints.",
|
||||
"Never show generic parameter hints.",
|
||||
"Only show const generic parameter hints."
|
||||
]
|
||||
},
|
||||
"AdjustmentHintsModeDef" => set! {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
|
@ -501,7 +501,9 @@ pub(crate) fn inlay_hint(
|
|||
padding_left: Some(inlay_hint.pad_left),
|
||||
padding_right: Some(inlay_hint.pad_right),
|
||||
kind: match inlay_hint.kind {
|
||||
InlayKind::Parameter => Some(lsp_types::InlayHintKind::PARAMETER),
|
||||
InlayKind::Parameter | InlayKind::GenericParameter => {
|
||||
Some(lsp_types::InlayHintKind::PARAMETER)
|
||||
}
|
||||
InlayKind::Type | InlayKind::Chaining => Some(lsp_types::InlayHintKind::TYPE),
|
||||
_ => None,
|
||||
},
|
||||
|
|
|
@ -655,6 +655,21 @@ Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
|
|||
--
|
||||
Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
|
||||
--
|
||||
[[rust-analyzer.inlayHints.genericParameterHints.const.enable]]rust-analyzer.inlayHints.genericParameterHints.const.enable (default: `false`)::
|
||||
+
|
||||
--
|
||||
Whether to show const generic parameter name inlay hints.
|
||||
--
|
||||
[[rust-analyzer.inlayHints.genericParameterHints.lifetime.enable]]rust-analyzer.inlayHints.genericParameterHints.lifetime.enable (default: `true`)::
|
||||
+
|
||||
--
|
||||
Whether to show generic lifetime parameter name inlay hints.
|
||||
--
|
||||
[[rust-analyzer.inlayHints.genericParameterHints.type.enable]]rust-analyzer.inlayHints.genericParameterHints.type.enable (default: `false`)::
|
||||
+
|
||||
--
|
||||
Whether to show generic type parameter name inlay hints.
|
||||
--
|
||||
[[rust-analyzer.inlayHints.implicitDrops.enable]]rust-analyzer.inlayHints.implicitDrops.enable (default: `false`)::
|
||||
+
|
||||
--
|
||||
|
|
|
@ -1909,6 +1909,36 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "inlayHints",
|
||||
"properties": {
|
||||
"rust-analyzer.inlayHints.genericParameterHints.const.enable": {
|
||||
"markdownDescription": "Whether to show const generic parameter name inlay hints.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "inlayHints",
|
||||
"properties": {
|
||||
"rust-analyzer.inlayHints.genericParameterHints.lifetime.enable": {
|
||||
"markdownDescription": "Whether to show generic lifetime parameter name inlay hints.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "inlayHints",
|
||||
"properties": {
|
||||
"rust-analyzer.inlayHints.genericParameterHints.type.enable": {
|
||||
"markdownDescription": "Whether to show generic type parameter name inlay hints.",
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "inlayHints",
|
||||
"properties": {
|
||||
|
|
Loading…
Reference in a new issue