From 169e69d217600062f6299f7f9521f3f2776d0333 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 23 Jul 2019 16:38:21 +0300 Subject: Show type decorators --- editors/code/src/commands/index.ts | 4 +- editors/code/src/commands/inlay_hints.ts | 142 +++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 editors/code/src/commands/inlay_hints.ts (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 194658497..d17f702e8 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -6,6 +6,7 @@ import * as onEnter from './on_enter'; import * as parentModule from './parent_module'; import * as runnables from './runnables'; import * as syntaxTree from './syntaxTree'; +import * as inlayHints from './inlay_hints'; export { analyzerStatus, @@ -15,5 +16,6 @@ export { parentModule, runnables, syntaxTree, - onEnter + onEnter, + inlayHints, }; diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts new file mode 100644 index 000000000..2780e9326 --- /dev/null +++ b/editors/code/src/commands/inlay_hints.ts @@ -0,0 +1,142 @@ +import * as vscode from 'vscode'; +import { DecorationOptions, Range, TextDocumentChangeEvent, TextDocumentContentChangeEvent, TextEditor } from 'vscode'; +import { TextDocumentIdentifier } from 'vscode-languageclient'; +import { Server } from '../server'; + +interface InlayHintsParams { + textDocument: TextDocumentIdentifier; +} + +interface InlayHint { + range: Range, + kind: string, + label: string, +} + +const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ + after: { + color: new vscode.ThemeColor('ralsp.inlayHint'), + }, +}); + +export class HintsUpdater { + private currentDecorations = new Map(); + private displayHints = true; + + public async loadHints(editor: vscode.TextEditor | undefined): Promise { + if (this.displayHints && editor !== undefined) { + await this.updateDecorationsFromServer(editor.document.uri.toString(), editor); + } + } + + public dropHints(document: vscode.TextDocument) { + if (this.displayHints) { + this.currentDecorations.delete(document.uri.toString()); + } + } + + public async toggleHintsDisplay(displayHints: boolean): Promise { + if (this.displayHints !== displayHints) { + this.displayHints = displayHints; + this.currentDecorations.clear(); + + if (displayHints) { + return this.updateHints(); + } else { + const editor = vscode.window.activeTextEditor; + if (editor != null) { + return editor.setDecorations(typeHintDecorationType, []) + } + } + } + } + + public async updateHints(cause?: TextDocumentChangeEvent): Promise { + if (!this.displayHints) { + return; + } + const editor = vscode.window.activeTextEditor; + if (editor == null) { + return; + } + const document = cause == null ? editor.document : cause.document; + if (document.languageId !== 'rust') { + return; + } + + const documentUri = document.uri.toString(); + const documentDecorators = this.currentDecorations.get(documentUri) || []; + + if (documentDecorators.length > 0) { + // FIXME a dbg! in the handlers.rs of the server causes + // an endless storm of events with `cause.contentChanges` with the dbg messages, why? + const changesFromFile = cause !== undefined ? cause.contentChanges.filter(changeEvent => this.isEventInFile(document.lineCount, changeEvent)) : []; + if (changesFromFile.length === 0) { + return; + } + + const firstShiftedLine = this.getFirstShiftedLine(changesFromFile); + if (firstShiftedLine !== null) { + const unchangedDecorations = documentDecorators.filter(decoration => decoration.range.start.line < firstShiftedLine); + if (unchangedDecorations.length !== documentDecorators.length) { + await editor.setDecorations(typeHintDecorationType, unchangedDecorations); + } + } + } + return await this.updateDecorationsFromServer(documentUri, editor); + } + + private isEventInFile(documentLineCount: number, event: TextDocumentContentChangeEvent): boolean { + const eventText = event.text; + if (eventText.length === 0) { + return event.range.start.line <= documentLineCount || event.range.end.line <= documentLineCount; + } else { + return event.range.start.line <= documentLineCount && event.range.end.line <= documentLineCount; + } + } + + private getFirstShiftedLine(changeEvents: TextDocumentContentChangeEvent[]): number | null { + let topmostUnshiftedLine: number | null = null; + + changeEvents + .filter(event => this.isShiftingChange(event)) + .forEach(event => { + const shiftedLineNumber = event.range.start.line; + if (topmostUnshiftedLine === null || topmostUnshiftedLine > shiftedLineNumber) { + topmostUnshiftedLine = shiftedLineNumber; + } + }); + + return topmostUnshiftedLine; + } + + private isShiftingChange(event: TextDocumentContentChangeEvent) { + const eventText = event.text; + if (eventText.length === 0) { + return !event.range.isSingleLine; + } else { + return eventText.indexOf('\n') >= 0 || eventText.indexOf('\r') >= 0; + } + } + + private async updateDecorationsFromServer(documentUri: string, editor: TextEditor): Promise { + const newHints = await this.queryHints(documentUri) || []; + const newDecorations = newHints.map(hint => ( + { + range: hint.range, + renderOptions: { after: { contentText: `: ${hint.label}` } }, + } + )); + this.currentDecorations.set(documentUri, newDecorations); + return editor.setDecorations(typeHintDecorationType, newDecorations); + } + + private async queryHints(documentUri: string): Promise { + const request: InlayHintsParams = { textDocument: { uri: documentUri } }; + const client = Server.client; + return client.onReady().then(() => client.sendRequest( + 'rust-analyzer/inlayHints', + request + )); + } +} -- cgit v1.2.3 From f7b8ae1ee7793bd9b34ecea27037a01159cd5d7a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 24 Jul 2019 17:15:12 +0300 Subject: Simplify the hints display --- editors/code/src/commands/inlay_hints.ts | 59 ++++---------------------------- 1 file changed, 6 insertions(+), 53 deletions(-) (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 2780e9326..cc6620d36 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { DecorationOptions, Range, TextDocumentChangeEvent, TextDocumentContentChangeEvent, TextEditor } from 'vscode'; +import { Range, TextDocumentChangeEvent, TextDocumentContentChangeEvent, TextEditor } from 'vscode'; import { TextDocumentIdentifier } from 'vscode-languageclient'; import { Server } from '../server'; @@ -20,7 +20,6 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ }); export class HintsUpdater { - private currentDecorations = new Map(); private displayHints = true; public async loadHints(editor: vscode.TextEditor | undefined): Promise { @@ -29,16 +28,9 @@ export class HintsUpdater { } } - public dropHints(document: vscode.TextDocument) { - if (this.displayHints) { - this.currentDecorations.delete(document.uri.toString()); - } - } - public async toggleHintsDisplay(displayHints: boolean): Promise { if (this.displayHints !== displayHints) { this.displayHints = displayHints; - this.currentDecorations.clear(); if (displayHints) { return this.updateHints(); @@ -64,26 +56,12 @@ export class HintsUpdater { return; } - const documentUri = document.uri.toString(); - const documentDecorators = this.currentDecorations.get(documentUri) || []; - - if (documentDecorators.length > 0) { - // FIXME a dbg! in the handlers.rs of the server causes - // an endless storm of events with `cause.contentChanges` with the dbg messages, why? - const changesFromFile = cause !== undefined ? cause.contentChanges.filter(changeEvent => this.isEventInFile(document.lineCount, changeEvent)) : []; - if (changesFromFile.length === 0) { - return; - } - - const firstShiftedLine = this.getFirstShiftedLine(changesFromFile); - if (firstShiftedLine !== null) { - const unchangedDecorations = documentDecorators.filter(decoration => decoration.range.start.line < firstShiftedLine); - if (unchangedDecorations.length !== documentDecorators.length) { - await editor.setDecorations(typeHintDecorationType, unchangedDecorations); - } - } + // If the dbg! macro is used in the lsp-server, an endless stream of events with `cause.contentChanges` with the dbg messages. + // Should not be a real situation, but better to filter such things out. + if (cause !== undefined && cause.contentChanges.filter(changeEvent => this.isEventInFile(document.lineCount, changeEvent)).length === 0) { + return; } - return await this.updateDecorationsFromServer(documentUri, editor); + return await this.updateDecorationsFromServer(document.uri.toString(), editor); } private isEventInFile(documentLineCount: number, event: TextDocumentContentChangeEvent): boolean { @@ -95,30 +73,6 @@ export class HintsUpdater { } } - private getFirstShiftedLine(changeEvents: TextDocumentContentChangeEvent[]): number | null { - let topmostUnshiftedLine: number | null = null; - - changeEvents - .filter(event => this.isShiftingChange(event)) - .forEach(event => { - const shiftedLineNumber = event.range.start.line; - if (topmostUnshiftedLine === null || topmostUnshiftedLine > shiftedLineNumber) { - topmostUnshiftedLine = shiftedLineNumber; - } - }); - - return topmostUnshiftedLine; - } - - private isShiftingChange(event: TextDocumentContentChangeEvent) { - const eventText = event.text; - if (eventText.length === 0) { - return !event.range.isSingleLine; - } else { - return eventText.indexOf('\n') >= 0 || eventText.indexOf('\r') >= 0; - } - } - private async updateDecorationsFromServer(documentUri: string, editor: TextEditor): Promise { const newHints = await this.queryHints(documentUri) || []; const newDecorations = newHints.map(hint => ( @@ -127,7 +81,6 @@ export class HintsUpdater { renderOptions: { after: { contentText: `: ${hint.label}` } }, } )); - this.currentDecorations.set(documentUri, newDecorations); return editor.setDecorations(typeHintDecorationType, newDecorations); } -- cgit v1.2.3 From 583f5c961239c806e9467da346967e75c87f6618 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 24 Jul 2019 19:52:26 +0300 Subject: Fix linter issues --- editors/code/src/commands/index.ts | 4 +- editors/code/src/commands/inlay_hints.ts | 88 ++++++++++++++++++++++---------- 2 files changed, 63 insertions(+), 29 deletions(-) (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index d17f702e8..c194bd2ea 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -1,12 +1,12 @@ import * as analyzerStatus from './analyzer_status'; import * as applySourceChange from './apply_source_change'; +import * as inlayHints from './inlay_hints'; import * as joinLines from './join_lines'; import * as matchingBrace from './matching_brace'; import * as onEnter from './on_enter'; import * as parentModule from './parent_module'; import * as runnables from './runnables'; import * as syntaxTree from './syntaxTree'; -import * as inlayHints from './inlay_hints'; export { analyzerStatus, @@ -17,5 +17,5 @@ export { runnables, syntaxTree, onEnter, - inlayHints, + inlayHints }; diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index cc6620d36..056d7c8e3 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -1,5 +1,10 @@ import * as vscode from 'vscode'; -import { Range, TextDocumentChangeEvent, TextDocumentContentChangeEvent, TextEditor } from 'vscode'; +import { + Range, + TextDocumentChangeEvent, + TextDocumentContentChangeEvent, + TextEditor +} from 'vscode'; import { TextDocumentIdentifier } from 'vscode-languageclient'; import { Server } from '../server'; @@ -8,23 +13,28 @@ interface InlayHintsParams { } interface InlayHint { - range: Range, - kind: string, - label: string, + range: Range; + kind: string; + label: string; } const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ after: { - color: new vscode.ThemeColor('ralsp.inlayHint'), - }, + color: new vscode.ThemeColor('ralsp.inlayHint') + } }); export class HintsUpdater { private displayHints = true; - public async loadHints(editor: vscode.TextEditor | undefined): Promise { + public async loadHints( + editor: vscode.TextEditor | undefined + ): Promise { if (this.displayHints && editor !== undefined) { - await this.updateDecorationsFromServer(editor.document.uri.toString(), editor); + await this.updateDecorationsFromServer( + editor.document.uri.toString(), + editor + ); } } @@ -37,7 +47,7 @@ export class HintsUpdater { } else { const editor = vscode.window.activeTextEditor; if (editor != null) { - return editor.setDecorations(typeHintDecorationType, []) + return editor.setDecorations(typeHintDecorationType, []); } } } @@ -58,38 +68,62 @@ export class HintsUpdater { // If the dbg! macro is used in the lsp-server, an endless stream of events with `cause.contentChanges` with the dbg messages. // Should not be a real situation, but better to filter such things out. - if (cause !== undefined && cause.contentChanges.filter(changeEvent => this.isEventInFile(document.lineCount, changeEvent)).length === 0) { + if ( + cause !== undefined && + cause.contentChanges.filter(changeEvent => + this.isEventInFile(document.lineCount, changeEvent) + ).length === 0 + ) { return; } - return await this.updateDecorationsFromServer(document.uri.toString(), editor); + return await this.updateDecorationsFromServer( + document.uri.toString(), + editor + ); } - private isEventInFile(documentLineCount: number, event: TextDocumentContentChangeEvent): boolean { + private isEventInFile( + documentLineCount: number, + event: TextDocumentContentChangeEvent + ): boolean { const eventText = event.text; if (eventText.length === 0) { - return event.range.start.line <= documentLineCount || event.range.end.line <= documentLineCount; + return ( + event.range.start.line <= documentLineCount || + event.range.end.line <= documentLineCount + ); } else { - return event.range.start.line <= documentLineCount && event.range.end.line <= documentLineCount; + return ( + event.range.start.line <= documentLineCount && + event.range.end.line <= documentLineCount + ); } } - private async updateDecorationsFromServer(documentUri: string, editor: TextEditor): Promise { - const newHints = await this.queryHints(documentUri) || []; - const newDecorations = newHints.map(hint => ( - { - range: hint.range, - renderOptions: { after: { contentText: `: ${hint.label}` } }, - } - )); + private async updateDecorationsFromServer( + documentUri: string, + editor: TextEditor + ): Promise { + const newHints = (await this.queryHints(documentUri)) || []; + const newDecorations = newHints.map(hint => ({ + range: hint.range, + renderOptions: { after: { contentText: `: ${hint.label}` } } + })); return editor.setDecorations(typeHintDecorationType, newDecorations); } private async queryHints(documentUri: string): Promise { - const request: InlayHintsParams = { textDocument: { uri: documentUri } }; + const request: InlayHintsParams = { + textDocument: { uri: documentUri } + }; const client = Server.client; - return client.onReady().then(() => client.sendRequest( - 'rust-analyzer/inlayHints', - request - )); + return client + .onReady() + .then(() => + client.sendRequest( + 'rust-analyzer/inlayHints', + request + ) + ); } } -- cgit v1.2.3 From bd904247bad2d213c25c0649ebd5e7a31e97135a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 24 Jul 2019 23:30:18 +0300 Subject: Remove unnecessary hacks --- editors/code/src/commands/inlay_hints.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 056d7c8e3..0ce3edcbf 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -2,7 +2,6 @@ import * as vscode from 'vscode'; import { Range, TextDocumentChangeEvent, - TextDocumentContentChangeEvent, TextEditor } from 'vscode'; import { TextDocumentIdentifier } from 'vscode-languageclient'; @@ -66,40 +65,12 @@ export class HintsUpdater { return; } - // If the dbg! macro is used in the lsp-server, an endless stream of events with `cause.contentChanges` with the dbg messages. - // Should not be a real situation, but better to filter such things out. - if ( - cause !== undefined && - cause.contentChanges.filter(changeEvent => - this.isEventInFile(document.lineCount, changeEvent) - ).length === 0 - ) { - return; - } return await this.updateDecorationsFromServer( document.uri.toString(), editor ); } - private isEventInFile( - documentLineCount: number, - event: TextDocumentContentChangeEvent - ): boolean { - const eventText = event.text; - if (eventText.length === 0) { - return ( - event.range.start.line <= documentLineCount || - event.range.end.line <= documentLineCount - ); - } else { - return ( - event.range.start.line <= documentLineCount && - event.range.end.line <= documentLineCount - ); - } - } - private async updateDecorationsFromServer( documentUri: string, editor: TextEditor -- cgit v1.2.3 From 02f18abc559930e5efec5af1ec4f3a7dbb8b4429 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 25 Jul 2019 15:17:37 +0300 Subject: Code review fixes --- editors/code/src/commands/inlay_hints.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index 0ce3edcbf..ba9966161 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -1,9 +1,5 @@ import * as vscode from 'vscode'; -import { - Range, - TextDocumentChangeEvent, - TextEditor -} from 'vscode'; +import { Range, TextDocumentChangeEvent, TextEditor } from 'vscode'; import { TextDocumentIdentifier } from 'vscode-languageclient'; import { Server } from '../server'; @@ -29,7 +25,7 @@ export class HintsUpdater { public async loadHints( editor: vscode.TextEditor | undefined ): Promise { - if (this.displayHints && editor !== undefined) { + if (this.displayHints && editor !== undefined && this.isRustDocument(editor.document)) { await this.updateDecorationsFromServer( editor.document.uri.toString(), editor @@ -61,7 +57,7 @@ export class HintsUpdater { return; } const document = cause == null ? editor.document : cause.document; - if (document.languageId !== 'rust') { + if (!this.isRustDocument(document)) { return; } @@ -71,6 +67,10 @@ export class HintsUpdater { ); } + private isRustDocument(document: vscode.TextDocument): boolean { + return document && document.languageId === 'rust'; + } + private async updateDecorationsFromServer( documentUri: string, editor: TextEditor -- cgit v1.2.3 From f1ba963a3097106ad6daa41d04c51b7f2d418d8c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 25 Jul 2019 15:54:20 +0300 Subject: npm run fix --- editors/code/src/commands/inlay_hints.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'editors/code/src/commands') diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index ba9966161..8154af8dc 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -25,7 +25,11 @@ export class HintsUpdater { public async loadHints( editor: vscode.TextEditor | undefined ): Promise { - if (this.displayHints && editor !== undefined && this.isRustDocument(editor.document)) { + if ( + this.displayHints && + editor !== undefined && + this.isRustDocument(editor.document) + ) { await this.updateDecorationsFromServer( editor.document.uri.toString(), editor -- cgit v1.2.3