Repository: rust-lang/rust-analyzer
Pull request #13037 (2022-08-16 14:53:38)

feat: Add a setting for keyword hover popups
This adds `rust-analyzer.hover.documentation.keywords.enable`, which defaults to `true` and can be turned off to disable the keyword documentation hover popups, which can be somewhat distracting when triggered by accident, and offer relatively little value if you're already familiar with the language.

Fixes https://github.com/rust-lang/rust-analyzer/issues/12950




Patch:
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index fa2c6f09ab..3687b597fc 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -27,6 +27,7 @@ use crate::{
 pub struct HoverConfig {
     pub links_in_hover: bool,
     pub documentation: Option<HoverDocFormat>,
+    pub keywords: bool,
 }
 
 impl HoverConfig {
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 6c50a4e6ad..d52adaee53 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -230,7 +230,7 @@ pub(super) fn keyword(
     config: &HoverConfig,
     token: &SyntaxToken,
 ) -> Option<HoverResult> {
-    if !token.kind().is_keyword() || !config.documentation.is_some() {
+    if !token.kind().is_keyword() || !config.documentation.is_some() || !config.keywords {
         return None;
     }
     let parent = token.parent()?;
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index cc79ee55b7..9e5eb90950 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -130,8 +130,11 @@ impl StaticIndex<'_> {
             syntax::NodeOrToken::Node(_) => None,
             syntax::NodeOrToken::Token(x) => Some(x),
         });
-        let hover_config =
-            HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) };
+        let hover_config = HoverConfig {
+            links_in_hover: true,
+            documentation: Some(HoverDocFormat::Markdown),
+            keywords: true,
+        };
         let tokens = tokens.filter(|token| {
             matches!(
                 token.kind(),
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 1629c1dd32..e63cfb163c 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -243,7 +243,10 @@ config_data! {
         hover_actions_run_enable: bool             = "true",
 
         /// Whether to show documentation on hover.
-        hover_documentation_enable: bool       = "true",
+        hover_documentation_enable: bool           = "true",
+        /// Whether to show keyword hover popups. Only applies when
+        /// `#rust-analyzer.hover.documentation.enable#` is set.
+        hover_documentation_keywords_enable: bool  = "true",
         /// Use markdown syntax for links in hover.
         hover_links_enable: bool = "true",
 
@@ -1187,6 +1190,7 @@ impl Config {
                     HoverDocFormat::PlainText
                 }
             }),
+            keywords: self.data.hover_documentation_keywords_enable,
         }
     }
 
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index b0f2f1614d..e3dbeec1fb 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -318,6 +318,12 @@ Whether to show `Run` action. Only applies when
 --
 Whether to show documentation on hover.
 --
+[[rust-analyzer.hover.documentation.keywords.enable]]rust-analyzer.hover.documentation.keywords.enable (default: `true`)::
++
+--
+Whether to show keyword hover popups. Only applies when
+`#rust-analyzer.hover.documentation.enable#` is set.
+--
 [[rust-analyzer.hover.links.enable]]rust-analyzer.hover.links.enable (default: `true`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index fbdc69c801..0714b356fe 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -756,6 +756,11 @@
                     "default": true,
                     "type": "boolean"
                 },
+                "rust-analyzer.hover.documentation.keywords.enable": {
+                    "markdownDescription": "Whether to show keyword hover popups. Only applies when\n`#rust-analyzer.hover.documentation.enable#` is set.",
+                    "default": true,
+                    "type": "boolean"
+                },
                 "rust-analyzer.hover.links.enable": {
                     "markdownDescription": "Use markdown syntax for links in hover.",
                     "default": true,


Test patch:
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index c6274264b8..685eb4521e 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -8,7 +8,11 @@ fn check_hover_no_result(ra_fixture: &str) {
     let (analysis, position) = fixture::position(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: true,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
         )
         .unwrap();
@@ -20,7 +24,11 @@ fn check(ra_fixture: &str, expect: Expect) {
     let (analysis, position) = fixture::position(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: true,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
         )
         .unwrap()
@@ -37,7 +45,11 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
     let (analysis, position) = fixture::position(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: false,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
         )
         .unwrap()
@@ -54,7 +66,11 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
     let (analysis, position) = fixture::position(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::PlainText) },
+            &HoverConfig {
+                links_in_hover: true,
+                documentation: Some(HoverDocFormat::PlainText),
+                keywords: true,
+            },
             FileRange { file_id: position.file_id, range: TextRange::empty(position.offset) },
         )
         .unwrap()
@@ -71,7 +87,11 @@ fn check_actions(ra_fixture: &str, expect: Expect) {
     let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: true, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: true,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             FileRange { file_id, range: position.range_or_empty() },
         )
         .unwrap()
@@ -83,7 +103,11 @@ fn check_hover_range(ra_fixture: &str, expect: Expect) {
     let (analysis, range) = fixture::range(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: false,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             range,
         )
         .unwrap()
@@ -95,7 +119,11 @@ fn check_hover_range_no_results(ra_fixture: &str) {
     let (analysis, range) = fixture::range(ra_fixture);
     let hover = analysis
         .hover(
-            &HoverConfig { links_in_hover: false, documentation: Some(HoverDocFormat::Markdown) },
+            &HoverConfig {
+                links_in_hover: false,
+                documentation: Some(HoverDocFormat::Markdown),
+                keywords: true,
+            },
             range,
         )
         .unwrap();