From 2c02aebeb560b6c388a8b94723042b1e25eb49e9 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 00:23:58 +0300 Subject: [PATCH 1/6] Query less hints on file open --- editors/code/src/commands/inlay_hints.ts | 52 ++++++++++++++++-------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 3ba9da48b66..5af3a69bcbf 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -21,32 +21,36 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ export class HintsUpdater { private displayHints = true; + private drawnDecorations = new Map(); - public async loadHints( - editor: vscode.TextEditor | undefined - ): Promise { - if ( - this.displayHints && - editor !== undefined && - this.isRustDocument(editor.document) - ) { - await this.updateDecorationsFromServer( - editor.document.uri.toString(), - editor - ); + public async loadHints(editor?: vscode.TextEditor): Promise { + if (this.displayHints) { + const documentUri = this.getEditorDocumentUri(editor); + if (documentUri !== null) { + const latestDecorations = this.drawnDecorations.get(documentUri); + if (latestDecorations === undefined) { + await this.updateDecorationsFromServer( + documentUri, + editor! + ); + } else { + await editor!.setDecorations(typeHintDecorationType, latestDecorations); + } + } } } public async toggleHintsDisplay(displayHints: boolean): Promise { if (this.displayHints !== displayHints) { this.displayHints = displayHints; + this.drawnDecorations.clear(); if (displayHints) { return this.updateHints(); } else { const editor = vscode.window.activeTextEditor; - if (editor != null) { - return editor.setDecorations(typeHintDecorationType, []); + if (this.getEditorDocumentUri(editor) !== null) { + return editor!.setDecorations(typeHintDecorationType, []); } } } @@ -85,10 +89,15 @@ export class HintsUpdater { range: hint.range, renderOptions: { after: { contentText: `: ${hint.label}` } } })); - return editor.setDecorations( - typeHintDecorationType, - newDecorations - ); + + this.drawnDecorations.set(documentUri, newDecorations); + + if (this.getEditorDocumentUri(vscode.window.activeTextEditor) === documentUri) { + return editor.setDecorations( + typeHintDecorationType, + newDecorations + ); + } } } @@ -106,4 +115,11 @@ export class HintsUpdater { ) ); } + + private getEditorDocumentUri(editor?: vscode.TextEditor): string | null { + if (editor && this.isRustDocument(editor.document)) { + return editor.document.uri.toString(); + } + return null; + } } From 15411d4474ceaacf10787f52c916ade3dea0eb49 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 00:28:36 +0300 Subject: [PATCH 2/6] Use proper inlay kinds --- crates/ra_ide_api/src/inlay_hints.rs | 42 ++++++------------- .../ra_lsp_server/src/main_loop/handlers.rs | 9 +--- crates/ra_lsp_server/src/req.rs | 7 +--- 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index a524e014f10..60a2c7cf57b 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs @@ -9,14 +9,9 @@ use ra_syntax::{ SmolStr, SyntaxKind, SyntaxNode, TextRange, }; -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Eq)] pub enum InlayKind { - LetBindingType, - ClosureParameterType, - ForExpressionBindingType, - IfExpressionType, - WhileLetExpressionType, - MatchArmType, + TypeHint, } #[derive(Debug)] @@ -46,7 +41,7 @@ fn get_inlay_hints( } let pat = let_statement.pat()?; let analyzer = SourceAnalyzer::new(db, file_id, let_statement.syntax(), None); - Some(get_pat_hints(db, &analyzer, pat, InlayKind::LetBindingType, false)) + Some(get_pat_type_hints(db, &analyzer, pat, false)) }) .visit(|closure_parameter: LambdaExpr| { let analyzer = SourceAnalyzer::new(db, file_id, closure_parameter.syntax(), None); @@ -55,15 +50,7 @@ fn get_inlay_hints( .params() .filter(|closure_param| closure_param.ascribed_type().is_none()) .filter_map(|closure_param| closure_param.pat()) - .map(|root_pat| { - get_pat_hints( - db, - &analyzer, - root_pat, - InlayKind::ClosureParameterType, - false, - ) - }) + .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false)) .flatten() .collect() }) @@ -71,17 +58,17 @@ fn get_inlay_hints( .visit(|for_expression: ForExpr| { let pat = for_expression.pat()?; let analyzer = SourceAnalyzer::new(db, file_id, for_expression.syntax(), None); - Some(get_pat_hints(db, &analyzer, pat, InlayKind::ForExpressionBindingType, false)) + Some(get_pat_type_hints(db, &analyzer, pat, false)) }) .visit(|if_expr: IfExpr| { let pat = if_expr.condition()?.pat()?; let analyzer = SourceAnalyzer::new(db, file_id, if_expr.syntax(), None); - Some(get_pat_hints(db, &analyzer, pat, InlayKind::IfExpressionType, true)) + Some(get_pat_type_hints(db, &analyzer, pat, true)) }) .visit(|while_expr: WhileExpr| { let pat = while_expr.condition()?.pat()?; let analyzer = SourceAnalyzer::new(db, file_id, while_expr.syntax(), None); - Some(get_pat_hints(db, &analyzer, pat, InlayKind::WhileLetExpressionType, true)) + Some(get_pat_type_hints(db, &analyzer, pat, true)) }) .visit(|match_arm_list: MatchArmList| { let analyzer = SourceAnalyzer::new(db, file_id, match_arm_list.syntax(), None); @@ -90,9 +77,7 @@ fn get_inlay_hints( .arms() .map(|match_arm| match_arm.pats()) .flatten() - .map(|root_pat| { - get_pat_hints(db, &analyzer, root_pat, InlayKind::MatchArmType, true) - }) + .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true)) .flatten() .collect(), ) @@ -100,11 +85,10 @@ fn get_inlay_hints( .accept(&node)? } -fn get_pat_hints( +fn get_pat_type_hints( db: &RootDatabase, analyzer: &SourceAnalyzer, root_pat: Pat, - kind: InlayKind, skip_root_pat_hint: bool, ) -> Vec { let original_pat = &root_pat.clone(); @@ -118,7 +102,7 @@ fn get_pat_hints( }) .map(|(range, pat_type)| InlayHint { range, - kind: kind.clone(), + kind: InlayKind::TypeHint, label: pat_type.display(db).to_string().into(), }) .collect() @@ -364,7 +348,7 @@ fn main() { if let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; if let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; if let CustomOption::Some(Test { b: y, .. }) = &test {}; - + if test == CustomOption::None {} }"#, ); @@ -425,7 +409,7 @@ fn main() { while let CustomOption::Some(Test { a: CustomOption::Some(x), b: y }) = &test {}; while let CustomOption::Some(Test { a: CustomOption::None, b: y }) = &test {}; while let CustomOption::Some(Test { b: y, .. }) = &test {}; - + while test == CustomOption::None {} }"#, ); @@ -445,7 +429,7 @@ fn main() { let (analysis, file_id) = single_file( r#" #[derive(PartialEq)] -enum CustomOption { +enum CustomOption { None, Some(T), } diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index c2a44ffa0f7..a6dc1f964e0 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -894,14 +894,7 @@ pub fn handle_inlay_hints( label: api_type.label.to_string(), range: api_type.range.conv_with(&line_index), kind: match api_type.kind { - ra_ide_api::InlayKind::LetBindingType => InlayKind::LetBindingType, - ra_ide_api::InlayKind::ClosureParameterType => InlayKind::ClosureParameterType, - ra_ide_api::InlayKind::ForExpressionBindingType => { - InlayKind::ForExpressionBindingType - } - ra_ide_api::InlayKind::IfExpressionType => InlayKind::IfExpressionType, - ra_ide_api::InlayKind::WhileLetExpressionType => InlayKind::WhileLetExpressionType, - ra_ide_api::InlayKind::MatchArmType => InlayKind::MatchArmType, + ra_ide_api::InlayKind::TypeHint => InlayKind::TypeHint, }, }) .collect()) diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 57043864382..6b986bcc938 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs @@ -213,12 +213,7 @@ pub struct InlayHintsParams { #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum InlayKind { - LetBindingType, - ClosureParameterType, - ForExpressionBindingType, - IfExpressionType, - WhileLetExpressionType, - MatchArmType, + TypeHint, } #[derive(Debug, Deserialize, Serialize)] From 3fb6462d54c498bfd8835dea29ead19d95099625 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 00:47:14 +0300 Subject: [PATCH 3/6] Style and test fixes --- crates/ra_ide_api/src/inlay_hints.rs | 56 ++++++++++++------------ editors/code/src/commands/inlay_hints.ts | 23 +++++++--- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/crates/ra_ide_api/src/inlay_hints.rs b/crates/ra_ide_api/src/inlay_hints.rs index 60a2c7cf57b..7b919031411 100644 --- a/crates/ra_ide_api/src/inlay_hints.rs +++ b/crates/ra_ide_api/src/inlay_hints.rs @@ -216,52 +216,52 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { range: [193; 197), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [236; 244), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [275; 279), - kind: LetBindingType, + kind: TypeHint, label: "&str", }, InlayHint { range: [539; 543), - kind: LetBindingType, + kind: TypeHint, label: "(i32, char)", }, InlayHint { range: [566; 567), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [570; 571), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [573; 574), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [584; 585), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [577; 578), - kind: LetBindingType, + kind: TypeHint, label: "f64", }, InlayHint { range: [580; 581), - kind: LetBindingType, + kind: TypeHint, label: "f64", }, ]"# @@ -283,12 +283,12 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { range: [21; 30), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [57; 66), - kind: ClosureParameterType, + kind: TypeHint, label: "i32", }, ]"# @@ -310,12 +310,12 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { range: [21; 30), - kind: LetBindingType, + kind: TypeHint, label: "i32", }, InlayHint { range: [44; 53), - kind: ForExpressionBindingType, + kind: TypeHint, label: "i32", }, ]"# @@ -356,27 +356,27 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { range: [166; 170), - kind: LetBindingType, + kind: TypeHint, label: "CustomOption", }, InlayHint { range: [334; 338), - kind: IfExpressionType, + kind: TypeHint, label: "&Test", }, InlayHint { range: [389; 390), - kind: IfExpressionType, + kind: TypeHint, label: "&CustomOption", }, InlayHint { range: [392; 393), - kind: IfExpressionType, + kind: TypeHint, label: "&u8", }, InlayHint { range: [531; 532), - kind: IfExpressionType, + kind: TypeHint, label: "&u32", }, ]"# @@ -417,7 +417,7 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { range: [166; 170), - kind: LetBindingType, + kind: TypeHint, label: "CustomOption", }, ]"# @@ -457,23 +457,23 @@ fn main() { assert_debug_snapshot_matches!(analysis.inlay_hints(file_id).unwrap(), @r#"[ InlayHint { - range: [312; 316), - kind: MatchArmType, + range: [311; 315), + kind: TypeHint, label: "Test", }, InlayHint { - range: [359; 360), - kind: MatchArmType, + range: [358; 359), + kind: TypeHint, label: "CustomOption", }, InlayHint { - range: [362; 363), - kind: MatchArmType, + range: [361; 362), + kind: TypeHint, label: "u8", }, InlayHint { - range: [485; 486), - kind: MatchArmType, + range: [484; 485), + kind: TypeHint, label: "u32", }, ]"# diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 5af3a69bcbf..11a2cfac5bc 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -27,14 +27,19 @@ export class HintsUpdater { if (this.displayHints) { const documentUri = this.getEditorDocumentUri(editor); if (documentUri !== null) { - const latestDecorations = this.drawnDecorations.get(documentUri); + const latestDecorations = this.drawnDecorations.get( + documentUri + ); if (latestDecorations === undefined) { await this.updateDecorationsFromServer( documentUri, editor! ); } else { - await editor!.setDecorations(typeHintDecorationType, latestDecorations); + await editor!.setDecorations( + typeHintDecorationType, + latestDecorations + ); } } } @@ -48,9 +53,12 @@ export class HintsUpdater { if (displayHints) { return this.updateHints(); } else { - const editor = vscode.window.activeTextEditor; - if (this.getEditorDocumentUri(editor) !== null) { - return editor!.setDecorations(typeHintDecorationType, []); + const currentEditor = vscode.window.activeTextEditor; + if (this.getEditorDocumentUri(currentEditor) !== null) { + return currentEditor!.setDecorations( + typeHintDecorationType, + [] + ); } } } @@ -92,7 +100,10 @@ export class HintsUpdater { this.drawnDecorations.set(documentUri, newDecorations); - if (this.getEditorDocumentUri(vscode.window.activeTextEditor) === documentUri) { + if ( + this.getEditorDocumentUri(vscode.window.activeTextEditor) === + documentUri + ) { return editor.setDecorations( typeHintDecorationType, newDecorations From f358b4c0c05b20bd438f5fe3082a53dbe5b90e88 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 11:07:27 +0300 Subject: [PATCH 4/6] Use WeakMap to avoid memory leaks --- editors/code/src/commands/inlay_hints.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 11a2cfac5bc..aad28d564a1 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -21,7 +21,10 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ export class HintsUpdater { private displayHints = true; - private drawnDecorations = new Map(); + private drawnDecorations = new WeakMap< + vscode.Uri, + vscode.DecorationOptions[] + >(); public async loadHints(editor?: vscode.TextEditor): Promise { if (this.displayHints) { @@ -48,7 +51,7 @@ export class HintsUpdater { public async toggleHintsDisplay(displayHints: boolean): Promise { if (this.displayHints !== displayHints) { this.displayHints = displayHints; - this.drawnDecorations.clear(); + this.drawnDecorations = new WeakMap(); if (displayHints) { return this.updateHints(); @@ -77,10 +80,7 @@ export class HintsUpdater { return; } - return await this.updateDecorationsFromServer( - document.uri.toString(), - editor - ); + return await this.updateDecorationsFromServer(document.uri, editor); } private isRustDocument(document: vscode.TextDocument): boolean { @@ -88,10 +88,10 @@ export class HintsUpdater { } private async updateDecorationsFromServer( - documentUri: string, + documentUri: vscode.Uri, editor: TextEditor ): Promise { - const newHints = await this.queryHints(documentUri); + const newHints = await this.queryHints(documentUri.toString()); if (newHints != null) { const newDecorations = newHints.map(hint => ({ range: hint.range, @@ -127,9 +127,11 @@ export class HintsUpdater { ); } - private getEditorDocumentUri(editor?: vscode.TextEditor): string | null { + private getEditorDocumentUri( + editor?: vscode.TextEditor + ): vscode.Uri | null { if (editor && this.isRustDocument(editor.document)) { - return editor.document.uri.toString(); + return editor.document.uri; } return null; } From 777552b6a8e534ef3780ecf30a432df1a48fd25c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 13:31:00 +0300 Subject: [PATCH 5/6] Cache decorations before the first change only --- editors/code/src/commands/inlay_hints.ts | 41 ++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index aad28d564a1..d6d1f61f9e4 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -21,8 +21,8 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ export class HintsUpdater { private displayHints = true; - private drawnDecorations = new WeakMap< - vscode.Uri, + private decorationsSinceLastChange = new Map< + string, vscode.DecorationOptions[] >(); @@ -30,8 +30,8 @@ export class HintsUpdater { if (this.displayHints) { const documentUri = this.getEditorDocumentUri(editor); if (documentUri !== null) { - const latestDecorations = this.drawnDecorations.get( - documentUri + const latestDecorations = this.decorationsSinceLastChange.get( + documentUri.toString() ); if (latestDecorations === undefined) { await this.updateDecorationsFromServer( @@ -51,7 +51,7 @@ export class HintsUpdater { public async toggleHintsDisplay(displayHints: boolean): Promise { if (this.displayHints !== displayHints) { this.displayHints = displayHints; - this.drawnDecorations = new WeakMap(); + this.decorationsSinceLastChange.clear(); if (displayHints) { return this.updateHints(); @@ -72,14 +72,15 @@ export class HintsUpdater { return; } const editor = vscode.window.activeTextEditor; - if (editor == null) { + if (editor === undefined) { return; } - const document = cause == null ? editor.document : cause.document; + const document = cause === undefined ? editor.document : cause.document; if (!this.isRustDocument(document)) { return; } + this.decorationsSinceLastChange.clear(); return await this.updateDecorationsFromServer(document.uri, editor); } @@ -92,23 +93,23 @@ export class HintsUpdater { editor: TextEditor ): Promise { const newHints = await this.queryHints(documentUri.toString()); - if (newHints != null) { + if ( + newHints !== null && + this.getEditorDocumentUri(vscode.window.activeTextEditor) === + documentUri + ) { const newDecorations = newHints.map(hint => ({ range: hint.range, renderOptions: { after: { contentText: `: ${hint.label}` } } })); - - this.drawnDecorations.set(documentUri, newDecorations); - - if ( - this.getEditorDocumentUri(vscode.window.activeTextEditor) === - documentUri - ) { - return editor.setDecorations( - typeHintDecorationType, - newDecorations - ); - } + this.decorationsSinceLastChange.set( + documentUri.toString(), + newDecorations + ); + return editor.setDecorations( + typeHintDecorationType, + newDecorations + ); } } From c5598d9ade92e9ec4474a14229bb34a44a4edad5 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 5 Aug 2019 22:31:12 +0300 Subject: [PATCH 6/6] Avoid shared mutable state --- editors/code/src/commands/inlay_hints.ts | 106 +++++++++-------------- editors/code/src/extension.ts | 20 ++++- 2 files changed, 55 insertions(+), 71 deletions(-) diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index d6d1f61f9e4..5393a2bc928 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -21,67 +21,57 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ export class HintsUpdater { private displayHints = true; - private decorationsSinceLastChange = new Map< - string, - vscode.DecorationOptions[] - >(); - - public async loadHints(editor?: vscode.TextEditor): Promise { - if (this.displayHints) { - const documentUri = this.getEditorDocumentUri(editor); - if (documentUri !== null) { - const latestDecorations = this.decorationsSinceLastChange.get( - documentUri.toString() - ); - if (latestDecorations === undefined) { - await this.updateDecorationsFromServer( - documentUri, - editor! - ); - } else { - await editor!.setDecorations( - typeHintDecorationType, - latestDecorations - ); - } - } - } - } public async toggleHintsDisplay(displayHints: boolean): Promise { if (this.displayHints !== displayHints) { this.displayHints = displayHints; - this.decorationsSinceLastChange.clear(); - - if (displayHints) { - return this.updateHints(); - } else { - const currentEditor = vscode.window.activeTextEditor; - if (this.getEditorDocumentUri(currentEditor) !== null) { - return currentEditor!.setDecorations( - typeHintDecorationType, - [] - ); - } - } + return this.refreshVisibleEditorsHints( + displayHints ? undefined : [] + ); } } - public async updateHints(cause?: TextDocumentChangeEvent): Promise { + public async refreshHintsForVisibleEditors( + cause?: TextDocumentChangeEvent + ): Promise { if (!this.displayHints) { return; } - const editor = vscode.window.activeTextEditor; - if (editor === undefined) { + if ( + cause !== undefined && + (cause.contentChanges.length === 0 || + !this.isRustDocument(cause.document)) + ) { return; } - const document = cause === undefined ? editor.document : cause.document; - if (!this.isRustDocument(document)) { - return; + return this.refreshVisibleEditorsHints(); + } + + private async refreshVisibleEditorsHints( + newDecorations?: vscode.DecorationOptions[] + ) { + const promises: Array> = []; + + for (const rustEditor of vscode.window.visibleTextEditors.filter( + editor => this.isRustDocument(editor.document) + )) { + if (newDecorations !== undefined) { + promises.push( + Promise.resolve( + rustEditor.setDecorations( + typeHintDecorationType, + newDecorations + ) + ) + ); + } else { + promises.push(this.updateDecorationsFromServer(rustEditor)); + } } - this.decorationsSinceLastChange.clear(); - return await this.updateDecorationsFromServer(document.uri, editor); + for (const promise of promises) { + await promise; + } } private isRustDocument(document: vscode.TextDocument): boolean { @@ -89,23 +79,14 @@ export class HintsUpdater { } private async updateDecorationsFromServer( - documentUri: vscode.Uri, editor: TextEditor ): Promise { - const newHints = await this.queryHints(documentUri.toString()); - if ( - newHints !== null && - this.getEditorDocumentUri(vscode.window.activeTextEditor) === - documentUri - ) { + const newHints = await this.queryHints(editor.document.uri.toString()); + if (newHints !== null) { const newDecorations = newHints.map(hint => ({ range: hint.range, renderOptions: { after: { contentText: `: ${hint.label}` } } })); - this.decorationsSinceLastChange.set( - documentUri.toString(), - newDecorations - ); return editor.setDecorations( typeHintDecorationType, newDecorations @@ -127,13 +108,4 @@ export class HintsUpdater { ) ); } - - private getEditorDocumentUri( - editor?: vscode.TextEditor - ): vscode.Uri | null { - if (editor && this.isRustDocument(editor.document)) { - return editor.document.uri; - } - return null; - } } diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts index c6efc2e7e04..39fe6efd889 100644 --- a/editors/code/src/extension.ts +++ b/editors/code/src/extension.ts @@ -151,15 +151,27 @@ export function activate(context: vscode.ExtensionContext) { if (Server.config.displayInlayHints) { const hintsUpdater = new HintsUpdater(); - hintsUpdater.loadHints(vscode.window.activeTextEditor).then(() => { + hintsUpdater.refreshHintsForVisibleEditors().then(() => { + // vscode may ignore top level hintsUpdater.refreshHintsForVisibleEditors() + // so update the hints once when the focus changes to guarantee their presence + let editorChangeDisposable: vscode.Disposable | null = null; + editorChangeDisposable = vscode.window.onDidChangeActiveTextEditor( + _ => { + if (editorChangeDisposable !== null) { + editorChangeDisposable.dispose(); + } + return hintsUpdater.refreshHintsForVisibleEditors(); + } + ); + disposeOnDeactivation( - vscode.window.onDidChangeActiveTextEditor(editor => - hintsUpdater.loadHints(editor) + vscode.window.onDidChangeVisibleTextEditors(_ => + hintsUpdater.refreshHintsForVisibleEditors() ) ); disposeOnDeactivation( vscode.workspace.onDidChangeTextDocument(e => - hintsUpdater.updateHints(e) + hintsUpdater.refreshHintsForVisibleEditors(e) ) ); disposeOnDeactivation(