From 6b118c9b8de3c3ed84a16aba2e71fa5a9ada6e74 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 19:58:44 +0100 Subject: Refactor runables --- editors/code/src/commands/index.ts | 5 +- editors/code/src/commands/runnables.ts | 122 ++++++++++++++++----------------- editors/code/src/main.ts | 6 +- 3 files changed, 66 insertions(+), 67 deletions(-) diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 325ae3da8..9f4636e52 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -8,7 +8,7 @@ import { parentModule } from './parent_module'; import { syntaxTree } from './syntax_tree'; import { expandMacro } from './expand_macro'; import * as inlayHints from './inlay_hints'; -import * as runnables from './runnables'; +import { run, runSingle } from './runnables'; function collectGarbage(ctx: Ctx): Cmd { return async () => { @@ -22,9 +22,10 @@ export { joinLines, matchingBrace, parentModule, - runnables, syntaxTree, onEnter, inlayHints, collectGarbage, + run, + runSingle }; diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 7728541de..c4be21a0c 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -1,7 +1,67 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; -import { Server } from '../server'; +import { Ctx, Cmd } from '../ctx'; + +export function run(ctx: Ctx): Cmd { + let prevRunnable: RunnableQuickPick | undefined; + + return async () => { + const editor = ctx.activeRustEditor; + if (!editor) return + + const textDocument: lc.TextDocumentIdentifier = { + uri: editor.document.uri.toString(), + }; + const params: RunnablesParams = { + textDocument, + position: ctx.client.code2ProtocolConverter.asPosition( + editor.selection.active, + ), + }; + const runnables = await ctx.client.sendRequest( + 'rust-analyzer/runnables', + params, + ); + const items: RunnableQuickPick[] = []; + if (prevRunnable) { + items.push(prevRunnable); + } + for (const r of runnables) { + if ( + prevRunnable && + JSON.stringify(prevRunnable.runnable) === JSON.stringify(r) + ) { + continue; + } + items.push(new RunnableQuickPick(r)); + } + const item = await vscode.window.showQuickPick(items); + if (!item) return; + + item.detail = 'rerun'; + prevRunnable = item; + const task = createTask(item.runnable); + return await vscode.tasks.executeTask(task); + } +} + +export function runSingle(ctx: Ctx): Cmd { + return async (runnable: Runnable) => { + const editor = ctx.activeRustEditor; + if (!editor) return + + const task = createTask(runnable); + task.group = vscode.TaskGroup.Build; + task.presentationOptions = { + reveal: vscode.TaskRevealKind.Always, + panel: vscode.TaskPanelKind.Dedicated, + clear: true, + }; + + return vscode.tasks.executeTask(task); + } +} interface RunnablesParams { textDocument: lc.TextDocumentIdentifier; @@ -67,63 +127,3 @@ function createTask(spec: Runnable): vscode.Task { t.presentationOptions.clear = true; return t; } - -let prevRunnable: RunnableQuickPick | undefined; -export async function handle(): Promise { - const editor = vscode.window.activeTextEditor; - if (editor == null || editor.document.languageId !== 'rust') { - return; - } - const textDocument: lc.TextDocumentIdentifier = { - uri: editor.document.uri.toString(), - }; - const params: RunnablesParams = { - textDocument, - position: Server.client.code2ProtocolConverter.asPosition( - editor.selection.active, - ), - }; - const runnables = await Server.client.sendRequest( - 'rust-analyzer/runnables', - params, - ); - const items: RunnableQuickPick[] = []; - if (prevRunnable) { - items.push(prevRunnable); - } - for (const r of runnables) { - if ( - prevRunnable && - JSON.stringify(prevRunnable.runnable) === JSON.stringify(r) - ) { - continue; - } - items.push(new RunnableQuickPick(r)); - } - const item = await vscode.window.showQuickPick(items); - if (!item) { - return; - } - - item.detail = 'rerun'; - prevRunnable = item; - const task = createTask(item.runnable); - return await vscode.tasks.executeTask(task); -} - -export async function handleSingle(runnable: Runnable) { - const editor = vscode.window.activeTextEditor; - if (editor == null || editor.document.languageId !== 'rust') { - return; - } - - const task = createTask(runnable); - task.group = vscode.TaskGroup.Build; - task.presentationOptions = { - reveal: vscode.TaskRevealKind.Always, - panel: vscode.TaskPanelKind.Dedicated, - clear: true, - }; - - return vscode.tasks.executeTask(task); -} diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index b8e3396a6..7ad5e6934 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -20,6 +20,8 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('parentModule', commands.parentModule); ctx.registerCommand('syntaxTree', commands.syntaxTree); ctx.registerCommand('expandMacro', commands.expandMacro); + ctx.registerCommand('run', commands.run); + ctx.registerCommand('runSingle', commands.runSingle); // Internal action for lenses function disposeOnDeactivation(disposable: vscode.Disposable) { context.subscriptions.push(disposable); @@ -29,10 +31,6 @@ export async function activate(context: vscode.ExtensionContext) { disposeOnDeactivation(vscode.commands.registerCommand(name, f)); } - // Commands are requests from vscode to the language server - registerCommand('rust-analyzer.run', commands.runnables.handle); - // Unlike the above this does not send requests to the language server - registerCommand('rust-analyzer.runSingle', commands.runnables.handleSingle); registerCommand( 'rust-analyzer.showReferences', (uri: string, position: lc.Position, locations: lc.Location[]) => { -- cgit v1.2.3 From da80b6c1e1c09831b2f30233ddacaf50fa58f812 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:00:46 +0100 Subject: Minor refactor --- editors/code/src/commands/inlay_hints.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts index ac7dcce60..6d00152f8 100644 --- a/editors/code/src/commands/inlay_hints.ts +++ b/editors/code/src/commands/inlay_hints.ts @@ -1,14 +1,13 @@ import * as vscode from 'vscode'; -import { Range, TextDocumentChangeEvent, TextEditor } from 'vscode'; -import { TextDocumentIdentifier } from 'vscode-languageclient'; +import * as lc from 'vscode-languageclient'; import { Server } from '../server'; interface InlayHintsParams { - textDocument: TextDocumentIdentifier; + textDocument: lc.TextDocumentIdentifier; } interface InlayHint { - range: Range; + range: vscode.Range; kind: string; label: string; } @@ -32,11 +31,10 @@ export class HintsUpdater { } public async refreshHintsForVisibleEditors( - cause?: TextDocumentChangeEvent, + cause?: vscode.TextDocumentChangeEvent, ): Promise { - if (!this.displayHints) { - return; - } + if (!this.displayHints) return; + if ( cause !== undefined && (cause.contentChanges.length === 0 || @@ -79,7 +77,7 @@ export class HintsUpdater { } private async updateDecorationsFromServer( - editor: TextEditor, + editor: vscode.TextEditor, ): Promise { const newHints = await this.queryHints(editor.document.uri.toString()); if (newHints !== null) { -- cgit v1.2.3 From 3d008a78d0ab1d43629326d58d4b2a157303dd00 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:07:04 +0100 Subject: Move all commands to ctx --- editors/code/src/commands/index.ts | 17 ++++++++++++++++- editors/code/src/commands/runnables.ts | 8 ++++---- editors/code/src/main.ts | 23 ++++++----------------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 9f4636e52..4a2e8e4db 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -1,3 +1,6 @@ +import * as vscode from 'vscode'; +import * as lc from 'vscode-languageclient'; + import { Ctx, Cmd } from '../ctx'; import { analyzerStatus } from './analyzer_status'; @@ -16,6 +19,17 @@ function collectGarbage(ctx: Ctx): Cmd { }; } +function showReferences(ctx: Ctx): Cmd { + return (uri: string, position: lc.Position, locations: lc.Location[]) => { + vscode.commands.executeCommand( + 'editor.action.showReferences', + vscode.Uri.parse(uri), + ctx.client.protocol2CodeConverter.asPosition(position), + locations.map(ctx.client.protocol2CodeConverter.asLocation), + ); + }; +} + export { analyzerStatus, expandMacro, @@ -27,5 +41,6 @@ export { inlayHints, collectGarbage, run, - runSingle + runSingle, + showReferences, }; diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index c4be21a0c..8cd86c21e 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -8,7 +8,7 @@ export function run(ctx: Ctx): Cmd { return async () => { const editor = ctx.activeRustEditor; - if (!editor) return + if (!editor) return; const textDocument: lc.TextDocumentIdentifier = { uri: editor.document.uri.toString(), @@ -43,13 +43,13 @@ export function run(ctx: Ctx): Cmd { prevRunnable = item; const task = createTask(item.runnable); return await vscode.tasks.executeTask(task); - } + }; } export function runSingle(ctx: Ctx): Cmd { return async (runnable: Runnable) => { const editor = ctx.activeRustEditor; - if (!editor) return + if (!editor) return; const task = createTask(runnable); task.group = vscode.TaskGroup.Build; @@ -60,7 +60,7 @@ export function runSingle(ctx: Ctx): Cmd { }; return vscode.tasks.executeTask(task); - } + }; } interface RunnablesParams { diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 7ad5e6934..4a3e1ab7c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -13,6 +13,8 @@ let ctx!: Ctx; export async function activate(context: vscode.ExtensionContext) { ctx = new Ctx(context); + + // Commands which invokes manually via command pallet, shortcut, etc. ctx.registerCommand('analyzerStatus', commands.analyzerStatus); ctx.registerCommand('collectGarbage', commands.collectGarbage); ctx.registerCommand('matchingBrace', commands.matchingBrace); @@ -21,28 +23,15 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('syntaxTree', commands.syntaxTree); ctx.registerCommand('expandMacro', commands.expandMacro); ctx.registerCommand('run', commands.run); - ctx.registerCommand('runSingle', commands.runSingle); // Internal action for lenses + + // Internal commands which are invoked by the server. + ctx.registerCommand('runSingle', commands.runSingle); + ctx.registerCommand('showReferences', commands.showReferences); function disposeOnDeactivation(disposable: vscode.Disposable) { context.subscriptions.push(disposable); } - function registerCommand(name: string, f: any) { - disposeOnDeactivation(vscode.commands.registerCommand(name, f)); - } - - registerCommand( - 'rust-analyzer.showReferences', - (uri: string, position: lc.Position, locations: lc.Location[]) => { - vscode.commands.executeCommand( - 'editor.action.showReferences', - vscode.Uri.parse(uri), - Server.client.protocol2CodeConverter.asPosition(position), - locations.map(Server.client.protocol2CodeConverter.asLocation), - ); - }, - ); - if (Server.config.enableEnhancedTyping) { ctx.overrideCommand('type', commands.onEnter); } -- cgit v1.2.3 From 7b199f6a4b7a947d1dad6a74b2b88758497d4efa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:10:40 +0100 Subject: Hints are not commands --- editors/code/src/commands/index.ts | 2 - editors/code/src/commands/inlay_hints.ts | 113 ------------------------------- editors/code/src/inlay_hints.ts | 113 +++++++++++++++++++++++++++++++ editors/code/src/main.ts | 2 +- 4 files changed, 114 insertions(+), 116 deletions(-) delete mode 100644 editors/code/src/commands/inlay_hints.ts create mode 100644 editors/code/src/inlay_hints.ts diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 4a2e8e4db..89af4be90 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -10,7 +10,6 @@ import { onEnter } from './on_enter'; import { parentModule } from './parent_module'; import { syntaxTree } from './syntax_tree'; import { expandMacro } from './expand_macro'; -import * as inlayHints from './inlay_hints'; import { run, runSingle } from './runnables'; function collectGarbage(ctx: Ctx): Cmd { @@ -38,7 +37,6 @@ export { parentModule, syntaxTree, onEnter, - inlayHints, collectGarbage, run, runSingle, diff --git a/editors/code/src/commands/inlay_hints.ts b/editors/code/src/commands/inlay_hints.ts deleted file mode 100644 index 6d00152f8..000000000 --- a/editors/code/src/commands/inlay_hints.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as vscode from 'vscode'; -import * as lc from 'vscode-languageclient'; -import { Server } from '../server'; - -interface InlayHintsParams { - textDocument: lc.TextDocumentIdentifier; -} - -interface InlayHint { - range: vscode.Range; - kind: string; - label: string; -} - -const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ - after: { - color: new vscode.ThemeColor('ralsp.inlayHint'), - }, -}); - -export class HintsUpdater { - private displayHints = true; - - public async toggleHintsDisplay(displayHints: boolean): Promise { - if (this.displayHints !== displayHints) { - this.displayHints = displayHints; - return this.refreshVisibleEditorsHints( - displayHints ? undefined : [], - ); - } - } - - public async refreshHintsForVisibleEditors( - cause?: vscode.TextDocumentChangeEvent, - ): Promise { - if (!this.displayHints) return; - - if ( - cause !== undefined && - (cause.contentChanges.length === 0 || - !this.isRustDocument(cause.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)); - } - } - - for (const promise of promises) { - await promise; - } - } - - private isRustDocument(document: vscode.TextDocument): boolean { - return document && document.languageId === 'rust'; - } - - private async updateDecorationsFromServer( - editor: vscode.TextEditor, - ): Promise { - 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}`, - }, - }, - })); - 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, - ), - ); - } -} diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts new file mode 100644 index 000000000..b975915ca --- /dev/null +++ b/editors/code/src/inlay_hints.ts @@ -0,0 +1,113 @@ +import * as vscode from 'vscode'; +import * as lc from 'vscode-languageclient'; +import { Server } from './server'; + +interface InlayHintsParams { + textDocument: lc.TextDocumentIdentifier; +} + +interface InlayHint { + range: vscode.Range; + kind: string; + label: string; +} + +const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ + after: { + color: new vscode.ThemeColor('ralsp.inlayHint'), + }, +}); + +export class HintsUpdater { + private displayHints = true; + + public async toggleHintsDisplay(displayHints: boolean): Promise { + if (this.displayHints !== displayHints) { + this.displayHints = displayHints; + return this.refreshVisibleEditorsHints( + displayHints ? undefined : [], + ); + } + } + + public async refreshHintsForVisibleEditors( + cause?: vscode.TextDocumentChangeEvent, + ): Promise { + if (!this.displayHints) return; + + if ( + cause !== undefined && + (cause.contentChanges.length === 0 || + !this.isRustDocument(cause.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)); + } + } + + for (const promise of promises) { + await promise; + } + } + + private isRustDocument(document: vscode.TextDocument): boolean { + return document && document.languageId === 'rust'; + } + + private async updateDecorationsFromServer( + editor: vscode.TextEditor, + ): Promise { + 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}`, + }, + }, + })); + 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, + ), + ); + } +} diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 4a3e1ab7c..cf0ddfa16 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as commands from './commands'; -import { HintsUpdater } from './commands/inlay_hints'; +import { HintsUpdater } from './inlay_hints'; import { StatusDisplay } from './commands/watch_status'; import * as events from './events'; import * as notifications from './notifications'; -- cgit v1.2.3 From 6cc55e4c5ce994be284fc4337eed21844c0eef24 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:16:07 +0100 Subject: status is not a command --- editors/code/src/commands/watch_status.ts | 105 ------------------------------ editors/code/src/main.ts | 12 ++-- editors/code/src/status_display.ts | 105 ++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 111 deletions(-) delete mode 100644 editors/code/src/commands/watch_status.ts create mode 100644 editors/code/src/status_display.ts diff --git a/editors/code/src/commands/watch_status.ts b/editors/code/src/commands/watch_status.ts deleted file mode 100644 index 10787b510..000000000 --- a/editors/code/src/commands/watch_status.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as vscode from 'vscode'; - -const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; - -export class StatusDisplay implements vscode.Disposable { - public packageName?: string; - - private i = 0; - private statusBarItem: vscode.StatusBarItem; - private command: string; - private timer?: NodeJS.Timeout; - - constructor(command: string) { - this.statusBarItem = vscode.window.createStatusBarItem( - vscode.StatusBarAlignment.Left, - 10, - ); - this.command = command; - this.statusBarItem.hide(); - } - - public show() { - this.packageName = undefined; - - this.timer = - this.timer || - setInterval(() => { - if (this.packageName) { - this.statusBarItem!.text = `cargo ${this.command} [${ - this.packageName - }] ${this.frame()}`; - } else { - this.statusBarItem!.text = `cargo ${ - this.command - } ${this.frame()}`; - } - }, 300); - - this.statusBarItem.show(); - } - - public hide() { - if (this.timer) { - clearInterval(this.timer); - this.timer = undefined; - } - - this.statusBarItem.hide(); - } - - public dispose() { - if (this.timer) { - clearInterval(this.timer); - this.timer = undefined; - } - - this.statusBarItem.dispose(); - } - - public handleProgressNotification(params: ProgressParams) { - const { token, value } = params; - if (token !== 'rustAnalyzer/cargoWatcher') { - return; - } - - switch (value.kind) { - case 'begin': - this.show(); - break; - - case 'report': - if (value.message) { - this.packageName = value.message; - } - break; - - case 'end': - this.hide(); - break; - } - } - - private frame() { - return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)]; - } -} - -// FIXME: Replace this once vscode-languageclient is updated to LSP 3.15 -interface ProgressParams { - token: string; - value: WorkDoneProgress; -} - -enum WorkDoneProgressKind { - Begin = 'begin', - Report = 'report', - End = 'end', -} - -interface WorkDoneProgress { - kind: WorkDoneProgressKind; - message?: string; - cancelable?: boolean; - percentage?: string; -} diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index cf0ddfa16..d6c210579 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -3,7 +3,7 @@ import * as lc from 'vscode-languageclient'; import * as commands from './commands'; import { HintsUpdater } from './inlay_hints'; -import { StatusDisplay } from './commands/watch_status'; +import { StatusDisplay } from './status_display'; import * as events from './events'; import * as notifications from './notifications'; import { Server } from './server'; @@ -28,10 +28,6 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('runSingle', commands.runSingle); ctx.registerCommand('showReferences', commands.showReferences); - function disposeOnDeactivation(disposable: vscode.Disposable) { - context.subscriptions.push(disposable); - } - if (Server.config.enableEnhancedTyping) { ctx.overrideCommand('type', commands.onEnter); } @@ -39,7 +35,11 @@ export async function activate(context: vscode.ExtensionContext) { const watchStatus = new StatusDisplay( Server.config.cargoWatchOptions.command, ); - disposeOnDeactivation(watchStatus); + ctx.pushCleanup(watchStatus); + + function disposeOnDeactivation(disposable: vscode.Disposable) { + context.subscriptions.push(disposable); + } // Notifications are events triggered by the language server const allNotifications: [string, lc.GenericNotificationHandler][] = [ diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts new file mode 100644 index 000000000..48cf0655b --- /dev/null +++ b/editors/code/src/status_display.ts @@ -0,0 +1,105 @@ +import * as vscode from 'vscode'; + +const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; + +export class StatusDisplay implements vscode.Disposable { + packageName?: string; + + private i = 0; + private statusBarItem: vscode.StatusBarItem; + private command: string; + private timer?: NodeJS.Timeout; + + constructor(command: string) { + this.statusBarItem = vscode.window.createStatusBarItem( + vscode.StatusBarAlignment.Left, + 10, + ); + this.command = command; + this.statusBarItem.hide(); + } + + show() { + this.packageName = undefined; + + this.timer = + this.timer || + setInterval(() => { + if (this.packageName) { + this.statusBarItem!.text = `cargo ${this.command} [${ + this.packageName + }] ${this.frame()}`; + } else { + this.statusBarItem!.text = `cargo ${ + this.command + } ${this.frame()}`; + } + }, 300); + + this.statusBarItem.show(); + } + + hide() { + if (this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } + + this.statusBarItem.hide(); + } + + dispose() { + if (this.timer) { + clearInterval(this.timer); + this.timer = undefined; + } + + this.statusBarItem.dispose(); + } + + handleProgressNotification(params: ProgressParams) { + const { token, value } = params; + if (token !== 'rustAnalyzer/cargoWatcher') { + return; + } + + switch (value.kind) { + case 'begin': + this.show(); + break; + + case 'report': + if (value.message) { + this.packageName = value.message; + } + break; + + case 'end': + this.hide(); + break; + } + } + + private frame() { + return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)]; + } +} + +// FIXME: Replace this once vscode-languageclient is updated to LSP 3.15 +interface ProgressParams { + token: string; + value: WorkDoneProgress; +} + +enum WorkDoneProgressKind { + Begin = 'begin', + Report = 'report', + End = 'end', +} + +interface WorkDoneProgress { + kind: WorkDoneProgressKind; + message?: string; + cancelable?: boolean; + percentage?: string; +} -- cgit v1.2.3 From b8368f09b4857a225ff9e59dd8977ed21c408536 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:16:57 +0100 Subject: Dead code --- editors/code/src/commands/line_buffer.ts | 16 ---------------- editors/code/src/status_display.ts | 4 ++-- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 editors/code/src/commands/line_buffer.ts diff --git a/editors/code/src/commands/line_buffer.ts b/editors/code/src/commands/line_buffer.ts deleted file mode 100644 index fb5b9f7f2..000000000 --- a/editors/code/src/commands/line_buffer.ts +++ /dev/null @@ -1,16 +0,0 @@ -export class LineBuffer { - private outBuffer: string = ''; - - public processOutput(chunk: string, cb: (line: string) => void) { - this.outBuffer += chunk; - let eolIndex = this.outBuffer.indexOf('\n'); - while (eolIndex >= 0) { - // line includes the EOL - const line = this.outBuffer.slice(0, eolIndex + 1); - cb(line); - this.outBuffer = this.outBuffer.slice(eolIndex + 1); - - eolIndex = this.outBuffer.indexOf('\n'); - } - } -} diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts index 48cf0655b..ed8573f02 100644 --- a/editors/code/src/status_display.ts +++ b/editors/code/src/status_display.ts @@ -28,11 +28,11 @@ export class StatusDisplay implements vscode.Disposable { if (this.packageName) { this.statusBarItem!.text = `cargo ${this.command} [${ this.packageName - }] ${this.frame()}`; + }] ${this.frame()}`; } else { this.statusBarItem!.text = `cargo ${ this.command - } ${this.frame()}`; + } ${this.frame()}`; } }, 300); -- cgit v1.2.3 From 9ead314005afd835ca64b5db9117e1c495814e17 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 30 Dec 2019 20:21:25 +0100 Subject: Encapsulate inlay hints activation --- editors/code/src/inlay_hints.ts | 38 +++++++++++++++++++++++++++++++++++++- editors/code/src/main.ts | 39 ++------------------------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index b975915ca..4581e2278 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -1,6 +1,42 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import { Server } from './server'; +import { Ctx } from './ctx'; + +export function activateInlayHints(ctx: Ctx) { + const hintsUpdater = new HintsUpdater(); + 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(); + }, + ); + + ctx.pushCleanup( + vscode.window.onDidChangeVisibleTextEditors(_ => + hintsUpdater.refreshHintsForVisibleEditors(), + ), + ); + ctx.pushCleanup( + vscode.workspace.onDidChangeTextDocument(e => + hintsUpdater.refreshHintsForVisibleEditors(e), + ), + ); + ctx.pushCleanup( + vscode.workspace.onDidChangeConfiguration(_ => + hintsUpdater.toggleHintsDisplay( + Server.config.displayInlayHints, + ), + ), + ); + }); +} interface InlayHintsParams { textDocument: lc.TextDocumentIdentifier; @@ -18,7 +54,7 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ }, }); -export class HintsUpdater { +class HintsUpdater { private displayHints = true; public async toggleHintsDisplay(displayHints: boolean): Promise { diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index d6c210579..7e63a9cac 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as commands from './commands'; -import { HintsUpdater } from './inlay_hints'; +import { activateInlayHints } from './inlay_hints'; import { StatusDisplay } from './status_display'; import * as events from './events'; import * as notifications from './notifications'; @@ -37,10 +37,6 @@ export async function activate(context: vscode.ExtensionContext) { ); ctx.pushCleanup(watchStatus); - function disposeOnDeactivation(disposable: vscode.Disposable) { - context.subscriptions.push(disposable); - } - // Notifications are events triggered by the language server const allNotifications: [string, lc.GenericNotificationHandler][] = [ [ @@ -71,38 +67,7 @@ export async function activate(context: vscode.ExtensionContext) { } if (Server.config.displayInlayHints) { - const hintsUpdater = new HintsUpdater(); - 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.onDidChangeVisibleTextEditors(_ => - hintsUpdater.refreshHintsForVisibleEditors(), - ), - ); - disposeOnDeactivation( - vscode.workspace.onDidChangeTextDocument(e => - hintsUpdater.refreshHintsForVisibleEditors(e), - ), - ); - disposeOnDeactivation( - vscode.workspace.onDidChangeConfiguration(_ => - hintsUpdater.toggleHintsDisplay( - Server.config.displayInlayHints, - ), - ), - ); - }); + activateInlayHints(ctx); } } -- cgit v1.2.3