aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--crates/ra_ide/Cargo.toml1
-rw-r--r--crates/ra_ide/src/inlay_hints.rs101
-rw-r--r--crates/ra_ide/src/lib.rs5
-rw-r--r--crates/ra_project_model/src/lib.rs29
-rw-r--r--crates/rust-analyzer/src/config.rs5
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--crates/rust-analyzer/src/world.rs4
-rw-r--r--docs/user/features.md4
-rw-r--r--editors/code/package.json20
-rw-r--r--editors/code/src/client.ts2
-rw-r--r--editors/code/src/config.ts13
-rw-r--r--editors/code/src/inlay_hints.ts2
13 files changed, 155 insertions, 34 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 330bdd1cb..6173741b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1028,6 +1028,7 @@ dependencies = [
1028 "ra_hir", 1028 "ra_hir",
1029 "ra_ide_db", 1029 "ra_ide_db",
1030 "ra_prof", 1030 "ra_prof",
1031 "ra_project_model",
1031 "ra_syntax", 1032 "ra_syntax",
1032 "ra_text_edit", 1033 "ra_text_edit",
1033 "rand", 1034 "rand",
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml
index 7235c944c..486832529 100644
--- a/crates/ra_ide/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -21,6 +21,7 @@ rustc-hash = "1.1.0"
21rand = { version = "0.7.3", features = ["small_rng"] } 21rand = { version = "0.7.3", features = ["small_rng"] }
22 22
23ra_syntax = { path = "../ra_syntax" } 23ra_syntax = { path = "../ra_syntax" }
24ra_project_model = { path = "../ra_project_model" }
24ra_text_edit = { path = "../ra_text_edit" } 25ra_text_edit = { path = "../ra_text_edit" }
25ra_db = { path = "../ra_db" } 26ra_db = { path = "../ra_db" }
26ra_ide_db = { path = "../ra_ide_db" } 27ra_ide_db = { path = "../ra_ide_db" }
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index cf0cbdbd0..0f1c13c14 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -3,6 +3,7 @@
3use hir::{Adt, HirDisplay, Semantics, Type}; 3use hir::{Adt, HirDisplay, Semantics, Type};
4use ra_ide_db::RootDatabase; 4use ra_ide_db::RootDatabase;
5use ra_prof::profile; 5use ra_prof::profile;
6use ra_project_model::{InlayHintDisplayType, InlayHintOptions};
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, 8 ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner},
8 match_ast, SmolStr, TextRange, 9 match_ast, SmolStr, TextRange,
@@ -26,7 +27,7 @@ pub struct InlayHint {
26pub(crate) fn inlay_hints( 27pub(crate) fn inlay_hints(
27 db: &RootDatabase, 28 db: &RootDatabase,
28 file_id: FileId, 29 file_id: FileId,
29 max_inlay_hint_length: Option<usize>, 30 inlay_hint_opts: &InlayHintOptions,
30) -> Vec<InlayHint> { 31) -> Vec<InlayHint> {
31 let _p = profile("inlay_hints"); 32 let _p = profile("inlay_hints");
32 let sema = Semantics::new(db); 33 let sema = Semantics::new(db);
@@ -36,9 +37,9 @@ pub(crate) fn inlay_hints(
36 for node in file.syntax().descendants() { 37 for node in file.syntax().descendants() {
37 match_ast! { 38 match_ast! {
38 match node { 39 match node {
39 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 40 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, inlay_hint_opts, ast::Expr::from(it)); },
40 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 41 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, inlay_hint_opts, ast::Expr::from(it)); },
41 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, max_inlay_hint_length, it); }, 42 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, inlay_hint_opts, it); },
42 _ => (), 43 _ => (),
43 } 44 }
44 } 45 }
@@ -49,8 +50,14 @@ pub(crate) fn inlay_hints(
49fn get_param_name_hints( 50fn get_param_name_hints(
50 acc: &mut Vec<InlayHint>, 51 acc: &mut Vec<InlayHint>,
51 sema: &Semantics<RootDatabase>, 52 sema: &Semantics<RootDatabase>,
53 inlay_hint_opts: &InlayHintOptions,
52 expr: ast::Expr, 54 expr: ast::Expr,
53) -> Option<()> { 55) -> Option<()> {
56 match inlay_hint_opts.display_type {
57 InlayHintDisplayType::Off | InlayHintDisplayType::TypeHints => return None,
58 _ => {}
59 }
60
54 let args = match &expr { 61 let args = match &expr {
55 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), 62 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
56 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), 63 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
@@ -84,9 +91,14 @@ fn get_param_name_hints(
84fn get_bind_pat_hints( 91fn get_bind_pat_hints(
85 acc: &mut Vec<InlayHint>, 92 acc: &mut Vec<InlayHint>,
86 sema: &Semantics<RootDatabase>, 93 sema: &Semantics<RootDatabase>,
87 max_inlay_hint_length: Option<usize>, 94 inlay_hint_opts: &InlayHintOptions,
88 pat: ast::BindPat, 95 pat: ast::BindPat,
89) -> Option<()> { 96) -> Option<()> {
97 match inlay_hint_opts.display_type {
98 InlayHintDisplayType::Off | InlayHintDisplayType::ParameterHints => return None,
99 _ => {}
100 }
101
90 let ty = sema.type_of_pat(&pat.clone().into())?; 102 let ty = sema.type_of_pat(&pat.clone().into())?;
91 103
92 if should_not_display_type_hint(sema.db, &pat, &ty) { 104 if should_not_display_type_hint(sema.db, &pat, &ty) {
@@ -96,7 +108,7 @@ fn get_bind_pat_hints(
96 acc.push(InlayHint { 108 acc.push(InlayHint {
97 range: pat.syntax().text_range(), 109 range: pat.syntax().text_range(),
98 kind: InlayKind::TypeHint, 110 kind: InlayKind::TypeHint,
99 label: ty.display_truncated(sema.db, max_inlay_hint_length).to_string().into(), 111 label: ty.display_truncated(sema.db, inlay_hint_opts.max_length).to_string().into(),
100 }); 112 });
101 Some(()) 113 Some(())
102} 114}
@@ -205,8 +217,63 @@ mod tests {
205 use insta::assert_debug_snapshot; 217 use insta::assert_debug_snapshot;
206 218
207 use crate::mock_analysis::single_file; 219 use crate::mock_analysis::single_file;
220 use ra_project_model::{InlayHintDisplayType, InlayHintOptions};
208 221
209 #[test] 222 #[test]
223 fn param_hints_only() {
224 let (analysis, file_id) = single_file(
225 r#"
226 fn foo(a: i32, b: i32) -> i32 { a + b }
227 fn main() {
228 let _x = foo(4, 4);
229 }"#,
230 );
231 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions{ display_type: InlayHintDisplayType::ParameterHints, max_length: None}).unwrap(), @r###"
232 [
233 InlayHint {
234 range: [106; 107),
235 kind: ParameterHint,
236 label: "a",
237 },
238 InlayHint {
239 range: [109; 110),
240 kind: ParameterHint,
241 label: "b",
242 },
243 ]"###);
244 }
245
246 #[test]
247 fn hints_disabled() {
248 let (analysis, file_id) = single_file(
249 r#"
250 fn foo(a: i32, b: i32) -> i32 { a + b }
251 fn main() {
252 let _x = foo(4, 4);
253 }"#,
254 );
255 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions{ display_type: InlayHintDisplayType::Off, max_length: None}).unwrap(), @r###"[]"###);
256 }
257
258 #[test]
259 fn type_hints_only() {
260 let (analysis, file_id) = single_file(
261 r#"
262 fn foo(a: i32, b: i32) -> i32 { a + b }
263 fn main() {
264 let _x = foo(4, 4);
265 }"#,
266 );
267 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions{ display_type: InlayHintDisplayType::TypeHints, max_length: None}).unwrap(), @r###"
268 [
269 InlayHint {
270 range: [97; 99),
271 kind: TypeHint,
272 label: "i32",
273 },
274 ]"###);
275 }
276 #[test]
210 fn default_generic_types_should_not_be_displayed() { 277 fn default_generic_types_should_not_be_displayed() {
211 let (analysis, file_id) = single_file( 278 let (analysis, file_id) = single_file(
212 r#" 279 r#"
@@ -221,7 +288,7 @@ fn main() {
221}"#, 288}"#,
222 ); 289 );
223 290
224 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 291 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
225 [ 292 [
226 InlayHint { 293 InlayHint {
227 range: [69; 71), 294 range: [69; 71),
@@ -278,7 +345,7 @@ fn main() {
278}"#, 345}"#,
279 ); 346 );
280 347
281 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 348 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
282 [ 349 [
283 InlayHint { 350 InlayHint {
284 range: [193; 197), 351 range: [193; 197),
@@ -358,7 +425,7 @@ fn main() {
358}"#, 425}"#,
359 ); 426 );
360 427
361 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 428 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
362 [ 429 [
363 InlayHint { 430 InlayHint {
364 range: [21; 30), 431 range: [21; 30),
@@ -422,7 +489,7 @@ fn main() {
422}"#, 489}"#,
423 ); 490 );
424 491
425 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 492 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
426 [ 493 [
427 InlayHint { 494 InlayHint {
428 range: [21; 30), 495 range: [21; 30),
@@ -472,7 +539,7 @@ fn main() {
472}"#, 539}"#,
473 ); 540 );
474 541
475 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 542 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
476 [ 543 [
477 InlayHint { 544 InlayHint {
478 range: [188; 192), 545 range: [188; 192),
@@ -567,7 +634,7 @@ fn main() {
567}"#, 634}"#,
568 ); 635 );
569 636
570 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 637 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
571 [ 638 [
572 InlayHint { 639 InlayHint {
573 range: [188; 192), 640 range: [188; 192),
@@ -662,7 +729,7 @@ fn main() {
662}"#, 729}"#,
663 ); 730 );
664 731
665 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 732 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
666 [ 733 [
667 InlayHint { 734 InlayHint {
668 range: [252; 256), 735 range: [252; 256),
@@ -734,7 +801,7 @@ fn main() {
734}"#, 801}"#,
735 ); 802 );
736 803
737 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 804 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(Some(8))).unwrap(), @r###"
738 [ 805 [
739 InlayHint { 806 InlayHint {
740 range: [74; 75), 807 range: [74; 75),
@@ -822,7 +889,7 @@ fn main() {
822}"#, 889}"#,
823 ); 890 );
824 891
825 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 892 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(None)).unwrap(), @r###"
826 [ 893 [
827 InlayHint { 894 InlayHint {
828 range: [798; 809), 895 range: [798; 809),
@@ -944,7 +1011,7 @@ fn main() {
944}"#, 1011}"#,
945 ); 1012 );
946 1013
947 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1014 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(Some(8))).unwrap(), @r###"
948 [] 1015 []
949 "### 1016 "###
950 ); 1017 );
@@ -970,7 +1037,7 @@ fn main() {
970}"#, 1037}"#,
971 ); 1038 );
972 1039
973 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1040 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintOptions::new(Some(8))).unwrap(), @r###"
974 [] 1041 []
975 "### 1042 "###
976 ); 1043 );
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 9f45003d3..8b1292a41 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -44,6 +44,7 @@ mod marks;
44#[cfg(test)] 44#[cfg(test)]
45mod test_utils; 45mod test_utils;
46 46
47use ra_project_model::InlayHintOptions;
47use std::sync::Arc; 48use std::sync::Arc;
48 49
49use ra_cfg::CfgOptions; 50use ra_cfg::CfgOptions;
@@ -318,9 +319,9 @@ impl Analysis {
318 pub fn inlay_hints( 319 pub fn inlay_hints(
319 &self, 320 &self,
320 file_id: FileId, 321 file_id: FileId,
321 max_inlay_hint_length: Option<usize>, 322 inlay_hint_opts: &InlayHintOptions,
322 ) -> Cancelable<Vec<InlayHint>> { 323 ) -> Cancelable<Vec<InlayHint>> {
323 self.with_db(|db| inlay_hints::inlay_hints(db, file_id, max_inlay_hint_length)) 324 self.with_db(|db| inlay_hints::inlay_hints(db, file_id, inlay_hint_opts))
324 } 325 }
325 326
326 /// Returns the set of folding ranges. 327 /// Returns the set of folding ranges.
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 37845ca56..a5012c0ef 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -16,6 +16,7 @@ use anyhow::{bail, Context, Result};
16use ra_cfg::CfgOptions; 16use ra_cfg::CfgOptions;
17use ra_db::{CrateGraph, CrateName, Edition, Env, FileId}; 17use ra_db::{CrateGraph, CrateName, Edition, Env, FileId};
18use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19use serde::Deserialize;
19use serde_json::from_reader; 20use serde_json::from_reader;
20 21
21pub use crate::{ 22pub use crate::{
@@ -24,6 +25,34 @@ pub use crate::{
24 sysroot::Sysroot, 25 sysroot::Sysroot,
25}; 26};
26 27
28#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
29#[serde(rename_all = "lowercase")]
30pub enum InlayHintDisplayType {
31 Off,
32 TypeHints,
33 ParameterHints,
34 Full,
35}
36
37#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
38#[serde(rename_all = "camelCase", default)]
39pub struct InlayHintOptions {
40 pub display_type: InlayHintDisplayType,
41 pub max_length: Option<usize>,
42}
43
44impl InlayHintOptions {
45 pub fn new(max_length: Option<usize>) -> Self {
46 Self { display_type: InlayHintDisplayType::Full, max_length }
47 }
48}
49
50impl Default for InlayHintOptions {
51 fn default() -> Self {
52 Self { display_type: InlayHintDisplayType::Full, max_length: None }
53 }
54}
55
27#[derive(Clone, PartialEq, Eq, Hash, Debug)] 56#[derive(Clone, PartialEq, Eq, Hash, Debug)]
28pub struct CargoTomlNotFoundError { 57pub struct CargoTomlNotFoundError {
29 pub searched_at: PathBuf, 58 pub searched_at: PathBuf,
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 3314269ec..1617eab0b 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -7,6 +7,7 @@
7//! configure the server itself, feature flags are passed into analysis, and 7//! configure the server itself, feature flags are passed into analysis, and
8//! tweak things like automatic insertion of `()` in completions. 8//! tweak things like automatic insertion of `()` in completions.
9 9
10use ra_project_model::InlayHintOptions;
10use rustc_hash::FxHashMap; 11use rustc_hash::FxHashMap;
11 12
12use ra_project_model::CargoFeatures; 13use ra_project_model::CargoFeatures;
@@ -30,7 +31,7 @@ pub struct ServerConfig {
30 31
31 pub lru_capacity: Option<usize>, 32 pub lru_capacity: Option<usize>,
32 33
33 pub max_inlay_hint_length: Option<usize>, 34 pub inlay_hint_opts: InlayHintOptions,
34 35
35 pub cargo_watch_enable: bool, 36 pub cargo_watch_enable: bool,
36 pub cargo_watch_args: Vec<String>, 37 pub cargo_watch_args: Vec<String>,
@@ -57,7 +58,7 @@ impl Default for ServerConfig {
57 exclude_globs: Vec::new(), 58 exclude_globs: Vec::new(),
58 use_client_watching: false, 59 use_client_watching: false,
59 lru_capacity: None, 60 lru_capacity: None,
60 max_inlay_hint_length: None, 61 inlay_hint_opts: Default::default(),
61 cargo_watch_enable: true, 62 cargo_watch_enable: true,
62 cargo_watch_args: Vec::new(), 63 cargo_watch_args: Vec::new(),
63 cargo_watch_command: "check".to_string(), 64 cargo_watch_command: "check".to_string(),
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index f9de712a0..91fb66abb 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -177,7 +177,7 @@ pub fn main_loop(
177 .and_then(|it| it.folding_range.as_ref()) 177 .and_then(|it| it.folding_range.as_ref())
178 .and_then(|it| it.line_folding_only) 178 .and_then(|it| it.line_folding_only)
179 .unwrap_or(false), 179 .unwrap_or(false),
180 max_inlay_hint_length: config.max_inlay_hint_length, 180 inlay_hint_opts: config.inlay_hint_opts.clone(),
181 cargo_watch: CheckOptions { 181 cargo_watch: CheckOptions {
182 enable: config.cargo_watch_enable, 182 enable: config.cargo_watch_enable,
183 args: config.cargo_watch_args, 183 args: config.cargo_watch_args,
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index 1ddc3c1a5..8043a6cd3 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -15,7 +15,7 @@ use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWa
15use ra_ide::{ 15use ra_ide::{
16 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, 16 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId,
17}; 17};
18use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace}; 18use ra_project_model::{get_rustc_cfg_options, InlayHintOptions, ProjectWorkspace};
19use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch}; 19use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
20use relative_path::RelativePathBuf; 20use relative_path::RelativePathBuf;
21 21
@@ -32,7 +32,7 @@ pub struct Options {
32 pub publish_decorations: bool, 32 pub publish_decorations: bool,
33 pub supports_location_link: bool, 33 pub supports_location_link: bool,
34 pub line_folding_only: bool, 34 pub line_folding_only: bool,
35 pub max_inlay_hint_length: Option<usize>, 35 pub inlay_hint_opts: InlayHintOptions,
36 pub rustfmt_args: Vec<String>, 36 pub rustfmt_args: Vec<String>,
37 pub cargo_watch: CheckOptions, 37 pub cargo_watch: CheckOptions,
38} 38}
diff --git a/docs/user/features.md b/docs/user/features.md
index ba4d50fa8..06bc7ded5 100644
--- a/docs/user/features.md
+++ b/docs/user/features.md
@@ -191,8 +191,8 @@ Two types of inlay hints are displayed currently:
191 191
192In VS Code, the following settings can be used to configure the inlay hints: 192In VS Code, the following settings can be used to configure the inlay hints:
193 193
194* `rust-analyzer.displayInlayHints` — toggles inlay hints display on or off 194* `rust-analyzer.inlayHintOpts.displayType` configure which types of inlay hints are shown.
195* `rust-analyzer.maxInlayHintLength` — shortens the hints if their length exceeds the value specified. If no value is specified (`null`), no shortening is applied. 195* `rust-analyzer.inlayHintOpts.maxLength` — shortens the hints if their length exceeds the value specified. If no value is specified (`null`), no shortening is applied.
196 196
197**Note:** VS Code does not have native support for inlay hints [yet](https://github.com/microsoft/vscode/issues/16221) and the hints are implemented using decorations. 197**Note:** VS Code does not have native support for inlay hints [yet](https://github.com/microsoft/vscode/issues/16221) and the hints are implemented using decorations.
198This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird: 198This approach has limitations, the caret movement and bracket highlighting near the edges of the hint may be weird:
diff --git a/editors/code/package.json b/editors/code/package.json
index 512885454..6f2275062 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -307,12 +307,24 @@
307 "exclusiveMinimum": true, 307 "exclusiveMinimum": true,
308 "description": "Number of syntax trees rust-analyzer keeps in memory" 308 "description": "Number of syntax trees rust-analyzer keeps in memory"
309 }, 309 },
310 "rust-analyzer.displayInlayHints": { 310 "rust-analyzer.inlayHintOpts.displayType": {
311 "type": "boolean", 311 "type": "string",
312 "default": true, 312 "enum": [
313 "off",
314 "typeHints",
315 "parameterHints",
316 "full"
317 ],
318 "enumDescriptions": [
319 "No type inlay hints",
320 "Type inlays hints only",
321 "Parameter inlays hints only",
322 "All inlay hints types"
323 ],
324 "default": "full",
313 "description": "Display additional type and parameter information in the editor" 325 "description": "Display additional type and parameter information in the editor"
314 }, 326 },
315 "rust-analyzer.maxInlayHintLength": { 327 "rust-analyzer.inlayHintOpts.maxLength": {
316 "type": [ 328 "type": [
317 "null", 329 "null",
318 "integer" 330 "integer"
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 540f7c9ea..ac4417c61 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -29,7 +29,7 @@ export async function createClient(config: Config, serverPath: string): Promise<
29 initializationOptions: { 29 initializationOptions: {
30 publishDecorations: !config.highlightingSemanticTokens, 30 publishDecorations: !config.highlightingSemanticTokens,
31 lruCapacity: config.lruCapacity, 31 lruCapacity: config.lruCapacity,
32 maxInlayHintLength: config.maxInlayHintLength, 32 inlayHintOpts: config.inlayHintOpts,
33 cargoWatchEnable: cargoWatchOpts.enable, 33 cargoWatchEnable: cargoWatchOpts.enable,
34 cargoWatchArgs: cargoWatchOpts.arguments, 34 cargoWatchArgs: cargoWatchOpts.arguments,
35 cargoWatchCommand: cargoWatchOpts.command, 35 cargoWatchCommand: cargoWatchOpts.command,
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index b72206d3c..5acce0752 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -5,6 +5,11 @@ import { log } from "./util";
5 5
6const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; 6const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG;
7 7
8export interface InlayHintOptions {
9 displayType: string;
10 maxLength: number;
11}
12
8export interface CargoWatchOptions { 13export interface CargoWatchOptions {
9 enable: boolean; 14 enable: boolean;
10 arguments: string[]; 15 arguments: string[];
@@ -149,8 +154,12 @@ export class Config {
149 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; } 154 get highlightingOn() { return this.cfg.get("highlightingOn") as boolean; }
150 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; } 155 get rainbowHighlightingOn() { return this.cfg.get("rainbowHighlightingOn") as boolean; }
151 get lruCapacity() { return this.cfg.get("lruCapacity") as null | number; } 156 get lruCapacity() { return this.cfg.get("lruCapacity") as null | number; }
152 get displayInlayHints() { return this.cfg.get("displayInlayHints") as boolean; } 157 get inlayHintOpts(): InlayHintOptions {
153 get maxInlayHintLength() { return this.cfg.get("maxInlayHintLength") as number; } 158 return {
159 displayType: this.cfg.get("inlayHintOpts.displayType") as string,
160 maxLength: this.cfg.get("inlayHintOpts.maxLength") as number,
161 };
162 }
154 get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; } 163 get excludeGlobs() { return this.cfg.get("excludeGlobs") as string[]; }
155 get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; } 164 get useClientWatching() { return this.cfg.get("useClientWatching") as boolean; }
156 get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; } 165 get featureFlags() { return this.cfg.get("featureFlags") as Record<string, boolean>; }
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index e1a82e03e..8d291406d 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -10,7 +10,7 @@ export function activateInlayHints(ctx: Ctx) {
10 const maybeUpdater = { 10 const maybeUpdater = {
11 updater: null as null | HintsUpdater, 11 updater: null as null | HintsUpdater,
12 onConfigChange() { 12 onConfigChange() {
13 if (!ctx.config.displayInlayHints) { 13 if (ctx.config.inlayHintOpts.displayType === 'off') {
14 return this.dispose(); 14 return this.dispose();
15 } 15 }
16 if (!this.updater) this.updater = new HintsUpdater(ctx); 16 if (!this.updater) this.updater = new HintsUpdater(ctx);