]> git.lizzy.rs Git - rust.git/commitdiff
Split hover actions config into its own config struct
authorLukas Wirth <lukastw97@gmail.com>
Mon, 21 Jun 2021 19:41:06 +0000 (21:41 +0200)
committerLukas Wirth <lukastw97@gmail.com>
Mon, 21 Jun 2021 19:47:54 +0000 (21:47 +0200)
crates/ide/src/hover.rs
crates/ide/src/lib.rs
crates/rust-analyzer/src/config.rs
crates/rust-analyzer/src/handlers.rs

index 0c1da87743cdf106618fa7ce29e692a04edf6bf0..35050899d19a0a9b8619696e29db57dcf5ef8988 100644 (file)
@@ -1,5 +1,5 @@
 use either::Either;
-use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay};
+use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics};
 use ide_db::{
     base_db::SourceDatabase,
     defs::{Definition, NameClass, NameRefClass},
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct HoverConfig {
-    pub implementations: bool,
-    pub references: bool,
-    pub run: bool,
-    pub debug: bool,
-    pub goto_type_def: bool,
     pub links_in_hover: bool,
     pub markdown: bool,
     pub documentation: bool,
 }
 
-impl HoverConfig {
-    pub const NO_ACTIONS: Self = Self {
-        implementations: false,
-        references: false,
-        run: false,
-        debug: false,
-        goto_type_def: false,
-        links_in_hover: true,
-        markdown: true,
-        documentation: true,
-    };
-
-    pub fn any_actions(&self) -> bool {
-        self.implementations || self.references || self.runnable() || self.goto_type_def
-    }
-
-    pub fn no_actions(&self) -> bool {
-        !self.any_actions()
-    }
-
-    pub fn runnable(&self) -> bool {
-        self.run || self.debug
-    }
-}
-
 #[derive(Debug, Clone)]
 pub enum HoverAction {
     Runnable(Runnable),
@@ -95,9 +65,7 @@ pub struct HoverResult {
 pub(crate) fn hover(
     db: &RootDatabase,
     position: FilePosition,
-    links_in_hover: bool,
-    documentation: bool,
-    markdown: bool,
+    config: &HoverConfig,
 ) -> Option<RangeInfo<HoverResult>> {
     let sema = hir::Semantics::new(db);
     let file = sema.parse(position.file_id).syntax().clone();
@@ -156,10 +124,14 @@ pub(crate) fn hover(
             }
             _ => None,
         };
-        if let Some(markup) =
-            hover_for_definition(db, definition, famous_defs.as_ref(), documentation)
-        {
-            res.markup = process_markup(sema.db, definition, &markup, links_in_hover, markdown);
+        if let Some(markup) = hover_for_definition(db, definition, famous_defs.as_ref(), config) {
+            res.markup = process_markup(
+                sema.db,
+                definition,
+                &markup,
+                config.links_in_hover,
+                config.markdown,
+            );
             if let Some(action) = show_implementations_action(db, definition) {
                 res.actions.push(action);
             }
@@ -181,8 +153,7 @@ pub(crate) fn hover(
         }
     }
 
-    if let res @ Some(_) = hover_for_keyword(&sema, links_in_hover, markdown, documentation, &token)
-    {
+    if let res @ Some(_) = hover_for_keyword(&sema, config, &token) {
         return res;
     }
 
@@ -201,7 +172,7 @@ pub(crate) fn hover(
         }
     };
 
-    res.markup = if markdown {
+    res.markup = if config.markdown {
         Markup::fenced_block(&ty.display(db))
     } else {
         ty.display(db).to_string().into()
@@ -428,7 +399,7 @@ fn hover_for_definition(
     db: &RootDatabase,
     def: Definition,
     famous_defs: Option<&FamousDefs>,
-    documentation: bool,
+    config: &HoverConfig,
 ) -> Option<Markup> {
     let mod_path = definition_mod_path(db, &def);
     let (label, docs) = match def {
@@ -466,7 +437,7 @@ fn hover_for_definition(
         Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))),
     };
 
-    return hover_markup(docs.filter(|_| documentation).map(Into::into), label, mod_path);
+    return hover_markup(docs.filter(|_| config.documentation).map(Into::into), label, mod_path);
 
     fn label_and_docs<D>(db: &RootDatabase, def: D) -> (String, Option<hir::Documentation>)
     where
@@ -502,13 +473,11 @@ fn hover_for_local(it: hir::Local, db: &RootDatabase) -> Option<Markup> {
 }
 
 fn hover_for_keyword(
-    sema: &hir::Semantics<RootDatabase>,
-    links_in_hover: bool,
-    markdown: bool,
-    documentation: bool,
+    sema: &Semantics<RootDatabase>,
+    config: &HoverConfig,
     token: &SyntaxToken,
 ) -> Option<RangeInfo<HoverResult>> {
-    if !token.kind().is_keyword() || !documentation {
+    if !token.kind().is_keyword() || !config.documentation {
         return None;
     }
     let famous_defs = FamousDefs(sema, sema.scope(&token.parent()?).krate());
@@ -520,8 +489,8 @@ fn hover_for_keyword(
         sema.db,
         Definition::ModuleDef(doc_owner.into()),
         &hover_markup(Some(docs.into()), token.text().into(), None)?,
-        links_in_hover,
-        markdown,
+        config.links_in_hover,
+        config.markdown,
     );
     Some(RangeInfo::new(token.text_range(), HoverResult { markup, actions: Default::default() }))
 }
@@ -561,16 +530,28 @@ mod tests {
     use expect_test::{expect, Expect};
     use ide_db::base_db::FileLoader;
 
-    use crate::fixture;
+    use crate::{fixture, HoverConfig};
 
     fn check_hover_no_result(ra_fixture: &str) {
         let (analysis, position) = fixture::position(ra_fixture);
-        assert!(analysis.hover(position, true, true, true).unwrap().is_none());
+        assert!(analysis
+            .hover(
+                position,
+                &HoverConfig { links_in_hover: true, markdown: true, documentation: true }
+            )
+            .unwrap()
+            .is_none());
     }
 
     fn check(ra_fixture: &str, expect: Expect) {
         let (analysis, position) = fixture::position(ra_fixture);
-        let hover = analysis.hover(position, true, true, true).unwrap().unwrap();
+        let hover = analysis
+            .hover(
+                position,
+                &HoverConfig { links_in_hover: true, markdown: true, documentation: true },
+            )
+            .unwrap()
+            .unwrap();
 
         let content = analysis.db.file_text(position.file_id);
         let hovered_element = &content[hover.range];
@@ -581,7 +562,13 @@ fn check(ra_fixture: &str, expect: Expect) {
 
     fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
         let (analysis, position) = fixture::position(ra_fixture);
-        let hover = analysis.hover(position, false, true, true).unwrap().unwrap();
+        let hover = analysis
+            .hover(
+                position,
+                &HoverConfig { links_in_hover: false, markdown: true, documentation: true },
+            )
+            .unwrap()
+            .unwrap();
 
         let content = analysis.db.file_text(position.file_id);
         let hovered_element = &content[hover.range];
@@ -592,7 +579,13 @@ fn check_hover_no_links(ra_fixture: &str, expect: Expect) {
 
     fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
         let (analysis, position) = fixture::position(ra_fixture);
-        let hover = analysis.hover(position, true, true, false).unwrap().unwrap();
+        let hover = analysis
+            .hover(
+                position,
+                &HoverConfig { links_in_hover: true, markdown: false, documentation: true },
+            )
+            .unwrap()
+            .unwrap();
 
         let content = analysis.db.file_text(position.file_id);
         let hovered_element = &content[hover.range];
@@ -603,7 +596,13 @@ fn check_hover_no_markdown(ra_fixture: &str, expect: Expect) {
 
     fn check_actions(ra_fixture: &str, expect: Expect) {
         let (analysis, position) = fixture::position(ra_fixture);
-        let hover = analysis.hover(position, true, true, true).unwrap().unwrap();
+        let hover = analysis
+            .hover(
+                position,
+                &HoverConfig { links_in_hover: true, markdown: true, documentation: true },
+            )
+            .unwrap()
+            .unwrap();
         expect.assert_debug_eq(&hover.info.actions)
     }
 
index aac084012869ad66775120db637fe3b7c7c9dbbf..e24a322185288f771fbc67b8cb7cd52b762e1555 100644 (file)
@@ -408,11 +408,9 @@ pub fn find_all_methods(&self, file_id: FileId) -> Cancellable<Vec<FileRange>> {
     pub fn hover(
         &self,
         position: FilePosition,
-        links_in_hover: bool,
-        documentation: bool,
-        markdown: bool,
+        config: &HoverConfig,
     ) -> Cancellable<Option<RangeInfo<HoverResult>>> {
-        self.with_db(|db| hover::hover(db, position, links_in_hover, documentation, markdown))
+        self.with_db(|db| hover::hover(db, position, config))
     }
 
     /// Return URL(s) for the documentation of the symbol under the cursor.
index 3aeca8839d7a62a43298c042084d2f1c31b5a56d..de70959a5381ae80e257f70c1f7ebc13db8b0a50 100644 (file)
@@ -32,6 +32,9 @@
 //
 // However, editor specific config, which the server doesn't know about, should
 // be specified directly in `package.json`.
+//
+// To deprecate an option by replacing it with another name use `new_name | `old_name` so that we keep
+// parsing the old name.
 config_data! {
     struct ConfigData {
         /// How imports should be grouped into use statements.
@@ -309,6 +312,37 @@ pub fn references(&self) -> bool {
     }
 }
 
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct HoverActionsConfig {
+    pub implementations: bool,
+    pub references: bool,
+    pub run: bool,
+    pub debug: bool,
+    pub goto_type_def: bool,
+}
+
+impl HoverActionsConfig {
+    pub const NO_ACTIONS: Self = Self {
+        implementations: false,
+        references: false,
+        run: false,
+        debug: false,
+        goto_type_def: false,
+    };
+
+    pub fn any(&self) -> bool {
+        self.implementations || self.references || self.runnable() || self.goto_type_def
+    }
+
+    pub fn none(&self) -> bool {
+        !self.any()
+    }
+
+    pub fn runnable(&self) -> bool {
+        self.run || self.debug
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct FilesConfig {
     pub watcher: FilesWatcher,
@@ -527,7 +561,7 @@ fn experimental(&self, index: &'static str) -> bool {
     pub fn code_action_group(&self) -> bool {
         self.experimental("codeActionGroup")
     }
-    pub fn hover_actions(&self) -> bool {
+    pub fn experimental_hover_actions(&self) -> bool {
         self.experimental("hoverActions")
     }
     pub fn server_status_notification(&self) -> bool {
@@ -727,17 +761,21 @@ pub fn lens(&self) -> LensConfig {
             refs: self.data.lens_enable && self.data.lens_references,
         }
     }
-    pub fn highlighting_strings(&self) -> bool {
-        self.data.highlighting_strings
-    }
-    pub fn hover(&self) -> HoverConfig {
-        HoverConfig {
+    pub fn hover_actions(&self) -> HoverActionsConfig {
+        HoverActionsConfig {
             implementations: self.data.hoverActions_enable
                 && self.data.hoverActions_implementations,
             references: self.data.hoverActions_enable && self.data.hoverActions_references,
             run: self.data.hoverActions_enable && self.data.hoverActions_run,
             debug: self.data.hoverActions_enable && self.data.hoverActions_debug,
             goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef,
+        }
+    }
+    pub fn highlighting_strings(&self) -> bool {
+        self.data.highlighting_strings
+    }
+    pub fn hover(&self) -> HoverConfig {
+        HoverConfig {
             links_in_hover: self.data.hover_linksInHover,
             markdown: try_or!(
                 self.caps
index eff1e6c93d805060616c1a7610e17347da348e82..dcead5f5c3af553f47746c8e1f3d663c39ed29a2 100644 (file)
@@ -861,13 +861,7 @@ pub(crate) fn handle_hover(
 ) -> Result<Option<lsp_ext::Hover>> {
     let _p = profile::span("handle_hover");
     let position = from_proto::file_position(&snap, params.text_document_position_params)?;
-    let hover_config = snap.config.hover();
-    let info = match snap.analysis.hover(
-        position,
-        hover_config.links_in_hover,
-        hover_config.documentation,
-        hover_config.markdown,
-    )? {
+    let info = match snap.analysis.hover(position, &snap.config.hover())? {
         None => return Ok(None),
         Some(info) => info,
     };
@@ -1487,7 +1481,7 @@ fn show_impl_command_link(
     snap: &GlobalStateSnapshot,
     position: &FilePosition,
 ) -> Option<lsp_ext::CommandLinkGroup> {
-    if snap.config.hover().implementations {
+    if snap.config.hover_actions().implementations {
         if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) {
             let uri = to_proto::url(snap, position.file_id);
             let line_index = snap.file_line_index(position.file_id).ok()?;
@@ -1513,7 +1507,7 @@ fn show_ref_command_link(
     snap: &GlobalStateSnapshot,
     position: &FilePosition,
 ) -> Option<lsp_ext::CommandLinkGroup> {
-    if snap.config.hover().references {
+    if snap.config.hover_actions().references {
         if let Some(ref_search_res) = snap.analysis.find_all_refs(*position, None).unwrap_or(None) {
             let uri = to_proto::url(snap, position.file_id);
             let line_index = snap.file_line_index(position.file_id).ok()?;
@@ -1544,8 +1538,8 @@ fn runnable_action_links(
     runnable: Runnable,
 ) -> Option<lsp_ext::CommandLinkGroup> {
     let cargo_spec = CargoTargetSpec::for_file(snap, runnable.nav.file_id).ok()?;
-    let hover_config = snap.config.hover();
-    if !hover_config.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) {
+    let hover_actions_config = snap.config.hover_actions();
+    if !hover_actions_config.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) {
         return None;
     }
 
@@ -1553,12 +1547,12 @@ fn runnable_action_links(
     to_proto::runnable(snap, runnable).ok().map(|r| {
         let mut group = lsp_ext::CommandLinkGroup::default();
 
-        if hover_config.run {
+        if hover_actions_config.run {
             let run_command = to_proto::command::run_single(&r, action.run_title);
             group.commands.push(to_command_link(run_command, r.label.clone()));
         }
 
-        if hover_config.debug {
+        if hover_actions_config.debug {
             let dbg_command = to_proto::command::debug_single(&r);
             group.commands.push(to_command_link(dbg_command, r.label));
         }
@@ -1571,7 +1565,7 @@ fn goto_type_action_links(
     snap: &GlobalStateSnapshot,
     nav_targets: &[HoverGotoTypeData],
 ) -> Option<lsp_ext::CommandLinkGroup> {
-    if !snap.config.hover().goto_type_def || nav_targets.is_empty() {
+    if !snap.config.hover_actions().goto_type_def || nav_targets.is_empty() {
         return None;
     }
 
@@ -1591,7 +1585,7 @@ fn prepare_hover_actions(
     snap: &GlobalStateSnapshot,
     actions: &[HoverAction],
 ) -> Vec<lsp_ext::CommandLinkGroup> {
-    if snap.config.hover().no_actions() || !snap.config.hover_actions() {
+    if snap.config.hover_actions().none() || !snap.config.experimental_hover_actions() {
         return Vec::new();
     }