Unnamed repository; edit this file 'description' to name the repository.
Add an option to minimize parentheses for adjustment hints
Maybe Waffle 2023-01-09
parent b89c4f0 · commit 12b7f9f
-rw-r--r--crates/ide/src/inlay_hints.rs14
-rw-r--r--crates/ide/src/inlay_hints/adjustment.rs111
-rw-r--r--crates/ide/src/lib.rs4
-rw-r--r--crates/ide/src/static_index.rs3
-rw-r--r--crates/rust-analyzer/src/config.rs35
-rw-r--r--docs/user/generated_config.adoc4
-rw-r--r--editors/code/package.json20
7 files changed, 162 insertions, 29 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 7315a37ebc..48a7bbfecf 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -35,7 +35,7 @@ pub struct InlayHintsConfig {
pub parameter_hints: bool,
pub chaining_hints: bool,
pub adjustment_hints: AdjustmentHints,
- pub adjustment_hints_postfix: bool,
+ pub adjustment_hints_mode: AdjustmentHintsMode,
pub adjustment_hints_hide_outside_unsafe: bool,
pub closure_return_type_hints: ClosureReturnTypeHints,
pub binding_mode_hints: bool,
@@ -75,6 +75,14 @@ pub enum AdjustmentHints {
Never,
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum AdjustmentHintsMode {
+ Prefix,
+ Postfix,
+ PreferPrefix,
+ PreferPostfix,
+}
+
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum InlayKind {
BindingModeHint,
@@ -432,7 +440,7 @@ mod tests {
use itertools::Itertools;
use test_utils::extract_annotations;
- use crate::inlay_hints::AdjustmentHints;
+ use crate::inlay_hints::{AdjustmentHints, AdjustmentHintsMode};
use crate::DiscriminantHints;
use crate::{fixture, inlay_hints::InlayHintsConfig, LifetimeElisionHints};
@@ -448,7 +456,7 @@ mod tests {
lifetime_elision_hints: LifetimeElisionHints::Never,
closure_return_type_hints: ClosureReturnTypeHints::Never,
adjustment_hints: AdjustmentHints::Never,
- adjustment_hints_postfix: false,
+ adjustment_hints_mode: AdjustmentHintsMode::Prefix,
adjustment_hints_hide_outside_unsafe: false,
binding_mode_hints: false,
hide_named_constructor_hints: false,
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index 367bd2f661..47e854e4bd 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -11,7 +11,7 @@ use syntax::{
ted,
};
-use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind};
+use crate::{AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintsConfig, InlayKind};
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
@@ -40,8 +40,8 @@ pub(super) fn hints(
let desc_expr = descended.as_ref().unwrap_or(expr);
let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
- let (needs_outer_parens, needs_inner_parens) =
- needs_parens_for_adjustment_hints(expr, config.adjustment_hints_postfix);
+ let (postfix, needs_outer_parens, needs_inner_parens) =
+ mode_and_needs_parens_for_adjustment_hints(expr, config.adjustment_hints_mode);
if needs_outer_parens {
acc.push(InlayHint {
@@ -52,7 +52,7 @@ pub(super) fn hints(
});
}
- if config.adjustment_hints_postfix && needs_inner_parens {
+ if postfix && needs_inner_parens {
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::OpeningParenthesis,
@@ -68,7 +68,7 @@ pub(super) fn hints(
}
let (mut tmp0, mut tmp1);
- let iter: &mut dyn Iterator<Item = _> = if config.adjustment_hints_postfix {
+ let iter: &mut dyn Iterator<Item = _> = if postfix {
tmp0 = adjustments.into_iter();
&mut tmp0
} else {
@@ -112,20 +112,16 @@ pub(super) fn hints(
};
acc.push(InlayHint {
range: expr.syntax().text_range(),
- kind: if config.adjustment_hints_postfix {
+ kind: if postfix {
InlayKind::AdjustmentHintPostfix
} else {
InlayKind::AdjustmentHint
},
- label: if config.adjustment_hints_postfix {
- format!(".{}", text.trim_end()).into()
- } else {
- text.into()
- },
+ label: if postfix { format!(".{}", text.trim_end()).into() } else { text.into() },
tooltip: None,
});
}
- if !config.adjustment_hints_postfix && needs_inner_parens {
+ if !postfix && needs_inner_parens {
acc.push(InlayHint {
range: expr.syntax().text_range(),
kind: InlayKind::OpeningParenthesis,
@@ -150,6 +146,41 @@ pub(super) fn hints(
Some(())
}
+/// Returns whatever the hint should be postfix and if we need to add paretheses on the inside and/or outside of `expr`,
+/// if we are going to add (`postfix`) adjustments hints to it.
+fn mode_and_needs_parens_for_adjustment_hints(
+ expr: &ast::Expr,
+ mode: AdjustmentHintsMode,
+) -> (bool, bool, bool) {
+ use {std::cmp::Ordering::*, AdjustmentHintsMode::*};
+
+ match mode {
+ Prefix | Postfix => {
+ let postfix = matches!(mode, Postfix);
+ let (inside, outside) = needs_parens_for_adjustment_hints(expr, postfix);
+ (postfix, inside, outside)
+ }
+ PreferPrefix | PreferPostfix => {
+ let prefer_postfix = matches!(mode, PreferPostfix);
+
+ let (pre_inside, pre_outside) = needs_parens_for_adjustment_hints(expr, false);
+ let prefix = (false, pre_inside, pre_outside);
+ let pre_count = pre_inside as u8 + pre_outside as u8;
+
+ let (post_inside, post_outside) = needs_parens_for_adjustment_hints(expr, true);
+ let postfix = (true, post_inside, post_outside);
+ let post_count = post_inside as u8 + post_outside as u8;
+
+ match pre_count.cmp(&post_count) {
+ Less => prefix,
+ Greater => postfix,
+ Equal if prefer_postfix => postfix,
+ Equal => prefix,
+ }
+ }
+ }
+}
+
/// Returns whatever we need to add paretheses on the inside and/or outside of `expr`,
/// if we are going to add (`postfix`) adjustments hints to it.
fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) {
@@ -217,7 +248,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool,
mod tests {
use crate::{
inlay_hints::tests::{check_with_config, DISABLED_CONFIG},
- AdjustmentHints, InlayHintsConfig,
+ AdjustmentHints, AdjustmentHintsMode, InlayHintsConfig,
};
#[test]
@@ -333,7 +364,7 @@ impl Struct {
check_with_config(
InlayHintsConfig {
adjustment_hints: AdjustmentHints::Always,
- adjustment_hints_postfix: true,
+ adjustment_hints_mode: AdjustmentHintsMode::Postfix,
..DISABLED_CONFIG
},
r#"
@@ -420,6 +451,58 @@ impl Struct {
}
#[test]
+ fn adjustment_hints_prefer_prefix() {
+ check_with_config(
+ InlayHintsConfig {
+ adjustment_hints: AdjustmentHints::Always,
+ adjustment_hints_mode: AdjustmentHintsMode::PreferPrefix,
+ ..DISABLED_CONFIG
+ },
+ r#"
+fn main() {
+ let _: u32 = loop {};
+ //^^^^^^^<never-to-any>
+
+ Struct.by_ref();
+ //^^^^^^.&
+
+ let (): () = return ();
+ //^^^^^^^^^<never-to-any>
+
+ struct Struct;
+ impl Struct { fn by_ref(&self) {} }
+}
+ "#,
+ )
+ }
+
+ #[test]
+ fn adjustment_hints_prefer_postfix() {
+ check_with_config(
+ InlayHintsConfig {
+ adjustment_hints: AdjustmentHints::Always,
+ adjustment_hints_mode: AdjustmentHintsMode::PreferPostfix,
+ ..DISABLED_CONFIG
+ },
+ r#"
+fn main() {
+ let _: u32 = loop {};
+ //^^^^^^^.<never-to-any>
+
+ Struct.by_ref();
+ //^^^^^^.&
+
+ let (): () = return ();
+ //^^^^^^^^^<never-to-any>
+
+ struct Struct;
+ impl Struct { fn by_ref(&self) {} }
+}
+ "#,
+ )
+ }
+
+ #[test]
fn never_to_never_is_never_shown() {
check_with_config(
InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 200958a433..239456cb28 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -81,8 +81,8 @@ pub use crate::{
highlight_related::{HighlightRelatedConfig, HighlightedRange},
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
inlay_hints::{
- AdjustmentHints, ClosureReturnTypeHints, DiscriminantHints, InlayHint, InlayHintLabel,
- InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
+ AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints, InlayHint,
+ InlayHintLabel, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
},
join_lines::JoinLinesConfig,
markup::Markup,
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index c6cca0d869..a6b30ba139 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -13,6 +13,7 @@ use syntax::{AstNode, SyntaxKind::*, SyntaxToken, TextRange, T};
use crate::{
hover::hover_for_definition,
+ inlay_hints::AdjustmentHintsMode,
moniker::{def_to_moniker, MonikerResult},
parent_module::crates_for,
Analysis, Fold, HoverConfig, HoverDocFormat, HoverResult, InlayHint, InlayHintsConfig,
@@ -115,7 +116,7 @@ impl StaticIndex<'_> {
closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
lifetime_elision_hints: crate::LifetimeElisionHints::Never,
adjustment_hints: crate::AdjustmentHints::Never,
- adjustment_hints_postfix: false,
+ adjustment_hints_mode: AdjustmentHintsMode::Prefix,
adjustment_hints_hide_outside_unsafe: false,
hide_named_constructor_hints: false,
hide_closure_initialization_hints: false,
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 4d11a84091..27a86db382 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -333,8 +333,8 @@ config_data! {
inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
/// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = "false",
- /// Whether to show inlay hints for type adjustments as postfix ops (`.*` instead of `*`, etc).
- inlayHints_expressionAdjustmentHints_postfix: bool = "false",
+ /// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
+ inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = "\"prefix\"",
/// Whether to show inlay type hints for elided lifetimes in function signatures.
inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
/// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
@@ -1254,7 +1254,12 @@ impl Config {
},
AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
},
- adjustment_hints_postfix: self.data.inlayHints_expressionAdjustmentHints_postfix,
+ adjustment_hints_mode: match self.data.inlayHints_expressionAdjustmentHints_mode {
+ AdjustmentHintsModeDef::Prefix => ide::AdjustmentHintsMode::Prefix,
+ AdjustmentHintsModeDef::Postfix => ide::AdjustmentHintsMode::Postfix,
+ AdjustmentHintsModeDef::PreferPrefix => ide::AdjustmentHintsMode::PreferPrefix,
+ AdjustmentHintsModeDef::PreferPostfix => ide::AdjustmentHintsMode::PreferPostfix,
+ },
adjustment_hints_hide_outside_unsafe: self
.data
.inlayHints_expressionAdjustmentHints_hideOutsideUnsafe,
@@ -1773,6 +1778,15 @@ enum DiscriminantHintsDef {
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
+enum AdjustmentHintsModeDef {
+ Prefix,
+ Postfix,
+ PreferPrefix,
+ PreferPostfix,
+}
+
+#[derive(Deserialize, Debug, Clone)]
+#[serde(rename_all = "snake_case")]
enum FilesWatcherDef {
Client,
Notify,
@@ -2104,6 +2118,21 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
"Only show discriminant hints on fieldless enum variants."
]
},
+ "AdjustmentHintsModeDef" => set! {
+ "type": "string",
+ "enum": [
+ "prefix",
+ "postfix",
+ "prefer_prefix",
+ "prefer_postfix",
+ ],
+ "enumDescriptions": [
+ "Always show adjustment hints as prefix (`*expr`).",
+ "Always show adjustment hints as postfix (`expr.*`).",
+ "Show prefix or postfix depending on which uses less parenthesis, prefering prefix.",
+ "Show prefix or postfix depending on which uses less parenthesis, prefering postfix.",
+ ]
+ },
"CargoFeaturesDef" => set! {
"anyOf": [
{
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 60c16ecadf..0aaf07ebf3 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -469,10 +469,10 @@ Whether to show inlay hints for type adjustments.
--
Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
--
-[[rust-analyzer.inlayHints.expressionAdjustmentHints.postfix]]rust-analyzer.inlayHints.expressionAdjustmentHints.postfix (default: `false`)::
+[[rust-analyzer.inlayHints.expressionAdjustmentHints.mode]]rust-analyzer.inlayHints.expressionAdjustmentHints.mode (default: `"prefix"`)::
+
--
-Whether to show inlay hints for type adjustments as postfix ops (`.*` instead of `*`, etc).
+Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).
--
[[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
+
diff --git a/editors/code/package.json b/editors/code/package.json
index aeb1d97c5f..5ffce2f553 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -1000,10 +1000,22 @@
"default": false,
"type": "boolean"
},
- "rust-analyzer.inlayHints.expressionAdjustmentHints.postfix": {
- "markdownDescription": "Whether to show inlay hints for type adjustments as postfix ops (`.*` instead of `*`, etc).",
- "default": false,
- "type": "boolean"
+ "rust-analyzer.inlayHints.expressionAdjustmentHints.mode": {
+ "markdownDescription": "Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc).",
+ "default": "prefix",
+ "type": "string",
+ "enum": [
+ "prefix",
+ "postfix",
+ "prefer_prefix",
+ "prefer_postfix"
+ ],
+ "enumDescriptions": [
+ "Always show adjustment hints as prefix (`*expr`).",
+ "Always show adjustment hints as postfix (`expr.*`).",
+ "Show prefix or postfix depending on which uses less parenthesis, prefering prefix.",
+ "Show prefix or postfix depending on which uses less parenthesis, prefering postfix."
+ ]
},
"rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
"markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",