From 94784cc546916f26ff9e312923a16463852e8e00 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 28 Jan 2020 17:00:00 +0100 Subject: Provide better diagnostics if the server is not in path --- editors/code/src/client.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 1ff64a930..15e1a0873 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -15,7 +15,13 @@ export function createClient(config: Config): lc.LanguageClient { const command = expandPathResolving(config.raLspServerPath); if (spawnSync(command, ["--version"]).status !== 0) { - window.showErrorMessage(`Unable to execute '${command} --version'`); + window.showErrorMessage( + `Unable to execute '${command} --version' + +Perhaps it is not in $PATH? + +PATH=${process.env.PATH} +`); } const run: lc.Executable = { command, -- cgit v1.2.3 From d4d72e8b9b3cc8b9ce72444a11e16cfa606a7f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 31 Jan 2020 20:55:10 +0200 Subject: Improve responsiveness of the cargo check status label --- editors/code/src/status_display.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts index c75fddf9d..7345bc3f5 100644 --- a/editors/code/src/status_display.ts +++ b/editors/code/src/status_display.ts @@ -17,7 +17,7 @@ export function activateStatusDisplay(ctx: Ctx) { class StatusDisplay implements vscode.Disposable { packageName?: string; - private i = 0; + private i: number = 0; private statusBarItem: vscode.StatusBarItem; private command: string; private timer?: NodeJS.Timeout; @@ -37,11 +37,8 @@ class StatusDisplay implements vscode.Disposable { this.timer = this.timer || setInterval(() => { - if (this.packageName) { - this.statusBarItem!.text = `${this.frame()} cargo ${this.command} [${this.packageName}]`; - } else { - this.statusBarItem!.text = `${this.frame()} cargo ${this.command}`; - } + this.tick(); + this.refreshLabel(); }, 300); this.statusBarItem.show(); @@ -65,6 +62,14 @@ class StatusDisplay implements vscode.Disposable { this.statusBarItem.dispose(); } + refreshLabel() { + if (this.packageName) { + this.statusBarItem!.text = `${spinnerFrames[this.i]} cargo ${this.command} [${this.packageName}]`; + } else { + this.statusBarItem!.text = `${spinnerFrames[this.i]} cargo ${this.command}`; + } + } + handleProgressNotification(params: WorkDoneProgressBegin | WorkDoneProgressReport | WorkDoneProgressEnd) { switch (params.kind) { case 'begin': @@ -74,6 +79,7 @@ class StatusDisplay implements vscode.Disposable { case 'report': if (params.message) { this.packageName = params.message; + this.refreshLabel(); } break; @@ -83,7 +89,7 @@ class StatusDisplay implements vscode.Disposable { } } - private frame() { - return spinnerFrames[(this.i = ++this.i % spinnerFrames.length)]; + private tick() { + this.i = (this.i + 1) % spinnerFrames.length; } } -- cgit v1.2.3 From f4431d2acc8e5dd25ed41c0c8af97050a7a230d1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 1 Feb 2020 13:12:39 +0100 Subject: [VSCode] Fix syntax highlighting Fixes #2969 --- editors/code/src/color_theme.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts index cbad47f35..e4d20490b 100644 --- a/editors/code/src/color_theme.ts +++ b/editors/code/src/color_theme.ts @@ -28,7 +28,9 @@ export class ColorTheme { static fromRules(rules: TextMateRule[]): ColorTheme { const res = new ColorTheme(); for (const rule of rules) { - const scopes = typeof rule.scope === 'string' + const scopes = typeof rule.scope === 'undefined' + ? [] + : typeof rule.scope === 'string' ? [rule.scope] : rule.scope; for (const scope of scopes) { -- cgit v1.2.3 From 5c39311f9639543fe1dd2a67ec5aff757bb830eb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 1 Feb 2020 13:39:04 +0100 Subject: Fix seedrandom in packaged extension Fixes #2971 --- editors/code/src/highlighting.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index 014e96f75..fc7cd5a1c 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -1,7 +1,6 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; -import * as seedrandom_ from 'seedrandom'; -const seedrandom = seedrandom_; // https://github.com/jvandemo/generator-angular2-library/issues/221#issuecomment-355945207 +import seedrandom from 'seedrandom'; import { ColorTheme, TextMateRuleSettings } from './color_theme'; -- cgit v1.2.3 From c84897bfb76b833122ee418d26e9bc53b4245ce8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 1 Feb 2020 13:41:11 +0100 Subject: Tsfmt --- editors/code/src/color_theme.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts index e4d20490b..d816f617d 100644 --- a/editors/code/src/color_theme.ts +++ b/editors/code/src/color_theme.ts @@ -31,8 +31,8 @@ export class ColorTheme { const scopes = typeof rule.scope === 'undefined' ? [] : typeof rule.scope === 'string' - ? [rule.scope] - : rule.scope; + ? [rule.scope] + : rule.scope; for (const scope of scopes) { res.rules.set(scope, rule.settings); } -- cgit v1.2.3 From 420462421d87a05c926501f8d4235f7660217924 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 21:12:59 +0200 Subject: vscode extension cleanup: migrate to prefer-const tslint rule --- editors/code/src/color_theme.ts | 2 +- editors/code/src/commands/index.ts | 2 +- editors/code/src/ctx.ts | 2 +- editors/code/src/highlighting.ts | 6 +++--- editors/code/src/inlay_hints.ts | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts index d816f617d..71113d374 100644 --- a/editors/code/src/color_theme.ts +++ b/editors/code/src/color_theme.ts @@ -69,7 +69,7 @@ function loadThemeNamed(themeName: string): ColorTheme { ); } - let themePaths = vscode.extensions.all + const themePaths = vscode.extensions.all .filter(isTheme) .flatMap(ext => { return ext.packageJSON.contributes.themes diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index dc075aa82..4501809e2 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -21,7 +21,7 @@ function collectGarbage(ctx: Ctx): Cmd { function showReferences(ctx: Ctx): Cmd { return (uri: string, position: lc.Position, locations: lc.Location[]) => { - let client = ctx.client; + const client = ctx.client; if (client) { vscode.commands.executeCommand( 'editor.action.showReferences', diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index a2a4e42a9..b882a8e52 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -20,7 +20,7 @@ export class Ctx { } async restartServer() { - let old = this.client; + const old = this.client; if (old) { await old.stop(); } diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index fc7cd5a1c..3d190c3ad 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -40,7 +40,7 @@ export function activateHighlighting(ctx: Ctx) { async (editor: vscode.TextEditor | undefined) => { if (!editor || editor.document.languageId !== 'rust') return; if (!ctx.config.highlightingOn) return; - let client = ctx.client; + const client = ctx.client; if (!client) return; const params: lc.TextDocumentIdentifier = { @@ -106,7 +106,7 @@ class Highlighter { } public setHighlights(editor: vscode.TextEditor, highlights: Decoration[]) { - let client = this.ctx.client; + const client = this.ctx.client; if (!client) return; // Initialize decorations if necessary // @@ -175,7 +175,7 @@ function initDecorations(): Map { const res = new Map(); TAG_TO_SCOPES.forEach((scopes, tag) => { if (!scopes) throw `unmapped tag: ${tag}`; - let rule = theme.lookup(scopes); + const rule = theme.lookup(scopes); const decor = createDecorationFromTextmate(rule); res.set(tag, decor); }); diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index 6357e44f1..ae7510183 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -127,13 +127,13 @@ class HintsUpdater { } private async queryHints(documentUri: string): Promise { - let client = this.ctx.client; + const client = this.ctx.client; if (!client) return null; const request: InlayHintsParams = { textDocument: { uri: documentUri }, }; - let tokenSource = new vscode.CancellationTokenSource(); - let prev = this.pending.get(documentUri); + const tokenSource = new vscode.CancellationTokenSource(); + const prev = this.pending.get(documentUri); if (prev) prev.cancel(); this.pending.set(documentUri, tokenSource); try { -- cgit v1.2.3 From 81847524702dd7cb1eeae25a53444b325295b129 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 21:37:22 +0200 Subject: vscode refactoring: use more laconic export snytax, split huge string to several lines --- editors/code/src/commands/index.ts | 45 ++++++++++++-------------------------- editors/code/src/ctx.ts | 4 +++- editors/code/src/main.ts | 2 +- 3 files changed, 18 insertions(+), 33 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 4501809e2..5a4c1df5e 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -4,22 +4,22 @@ import * as lc from 'vscode-languageclient'; import { Ctx, Cmd } from '../ctx'; import * as sourceChange from '../source_change'; -import { analyzerStatus } from './analyzer_status'; -import { matchingBrace } from './matching_brace'; -import { joinLines } from './join_lines'; -import { onEnter } from './on_enter'; -import { parentModule } from './parent_module'; -import { syntaxTree } from './syntax_tree'; -import { expandMacro } from './expand_macro'; -import { run, runSingle } from './runnables'; - -function collectGarbage(ctx: Ctx): Cmd { +export * from './analyzer_status'; +export * from './matching_brace'; +export * from './join_lines'; +export * from './on_enter'; +export * from './parent_module'; +export * from './syntax_tree'; +export * from './expand_macro'; +export * from './runnables'; + +export function collectGarbage(ctx: Ctx): Cmd { return async () => { ctx.client?.sendRequest('rust-analyzer/collectGarbage', null); }; } -function showReferences(ctx: Ctx): Cmd { +export function showReferences(ctx: Ctx): Cmd { return (uri: string, position: lc.Position, locations: lc.Location[]) => { const client = ctx.client; if (client) { @@ -33,13 +33,13 @@ function showReferences(ctx: Ctx): Cmd { }; } -function applySourceChange(ctx: Ctx): Cmd { +export function applySourceChange(ctx: Ctx): Cmd { return async (change: sourceChange.SourceChange) => { sourceChange.applySourceChange(ctx, change); }; } -function selectAndApplySourceChange(ctx: Ctx): Cmd { +export function selectAndApplySourceChange(ctx: Ctx): Cmd { return async (changes: sourceChange.SourceChange[]) => { if (changes.length === 1) { await sourceChange.applySourceChange(ctx, changes[0]); @@ -51,26 +51,9 @@ function selectAndApplySourceChange(ctx: Ctx): Cmd { }; } -function reload(ctx: Ctx): Cmd { +export function reload(ctx: Ctx): Cmd { return async () => { vscode.window.showInformationMessage('Reloading rust-analyzer...'); await ctx.restartServer(); }; } - -export { - analyzerStatus, - expandMacro, - joinLines, - matchingBrace, - parentModule, - syntaxTree, - onEnter, - collectGarbage, - run, - runSingle, - showReferences, - applySourceChange, - selectAndApplySourceChange, - reload -}; diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index b882a8e52..094566d09 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -66,7 +66,9 @@ export class Ctx { this.pushCleanup(d); } catch (_) { vscode.window.showWarningMessage( - 'Enhanced typing feature is disabled because of incompatibility with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings', + 'Enhanced typing feature is disabled because of incompatibility ' + + 'with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: ' + + 'https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings', ); } } diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 0494ccf63..de45f660b 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -11,7 +11,7 @@ let ctx!: Ctx; export async function activate(context: vscode.ExtensionContext) { ctx = new Ctx(context); - // Commands which invokes manually via command pallet, shortcut, etc. + // Commands which invokes manually via command pallete, shortcut, etc. ctx.registerCommand('analyzerStatus', commands.analyzerStatus); ctx.registerCommand('collectGarbage', commands.collectGarbage); ctx.registerCommand('matchingBrace', commands.matchingBrace); -- cgit v1.2.3 From 4bf5f595604c2c3fa0ca981a843d04a8732dabf9 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 21:38:49 +0200 Subject: vscode: fix type --- editors/code/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index de45f660b..6813c3c4c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -11,7 +11,7 @@ let ctx!: Ctx; export async function activate(context: vscode.ExtensionContext) { ctx = new Ctx(context); - // Commands which invokes manually via command pallete, shortcut, etc. + // Commands which invokes manually via command palette, shortcut, etc. ctx.registerCommand('analyzerStatus', commands.analyzerStatus); ctx.registerCommand('collectGarbage', commands.collectGarbage); ctx.registerCommand('matchingBrace', commands.matchingBrace); -- cgit v1.2.3 From 12d0970f7e4c4d7f91cccb12525fceea3c4c0669 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 22:19:59 +0200 Subject: vscode extension: migrate from any to unknown where possible --- editors/code/src/client.ts | 2 +- editors/code/src/color_theme.ts | 2 +- editors/code/src/commands/syntax_tree.ts | 2 +- editors/code/src/ctx.ts | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 15e1a0873..1778c4e9f 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -68,7 +68,7 @@ PATH=${process.env.PATH} // This also requires considering our settings strategy, which is work which needs doing // @ts-ignore The tracer is private to vscode-languageclient, but we need access to it to not log publishDecorations requests res._tracer = { - log: (messageOrDataObject: string | any, data?: string) => { + log: (messageOrDataObject: string | unknown, data?: string) => { if (typeof messageOrDataObject === 'string') { if ( messageOrDataObject.includes( diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts index 71113d374..7e10c7f79 100644 --- a/editors/code/src/color_theme.ts +++ b/editors/code/src/color_theme.ts @@ -61,7 +61,7 @@ export class ColorTheme { } function loadThemeNamed(themeName: string): ColorTheme { - function isTheme(extension: vscode.Extension): boolean { + function isTheme(extension: vscode.Extension): boolean { return ( extension.extensionKind === vscode.ExtensionKind.UI && extension.packageJSON.contributes && diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts index 02ea9f166..562df50cd 100644 --- a/editors/code/src/commands/syntax_tree.ts +++ b/editors/code/src/commands/syntax_tree.ts @@ -55,7 +55,7 @@ export function syntaxTree(ctx: Ctx): Cmd { // We need to order this after LS updates, but there's no API for that. // Hence, good old setTimeout. -function afterLs(f: () => any) { +function afterLs(f: () => unknown) { setTimeout(f, 10); } diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 094566d09..aae2c5f90 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -52,12 +52,12 @@ export class Ctx { overrideCommand(name: string, factory: (ctx: Ctx) => Cmd) { const defaultCmd = `default:${name}`; const override = factory(this); - const original = (...args: any[]) => + const original = (...args: unknown[]) => vscode.commands.executeCommand(defaultCmd, ...args); try { const d = vscode.commands.registerCommand( name, - async (...args: any[]) => { + async (...args: unknown[]) => { if (!(await override(...args))) { return await original(...args); } @@ -73,11 +73,11 @@ export class Ctx { } } - get subscriptions(): { dispose(): any }[] { + get subscriptions(): { dispose(): unknown }[] { return this.extCtx.subscriptions; } - pushCleanup(d: { dispose(): any }) { + pushCleanup(d: { dispose(): unknown }) { this.extCtx.subscriptions.push(d); } @@ -86,12 +86,12 @@ export class Ctx { } } -export type Cmd = (...args: any[]) => any; +export type Cmd = (...args: unknown[]) => unknown; export async function sendRequestWithRetry( client: lc.LanguageClient, method: string, - param: any, + param: unknown, token?: vscode.CancellationToken, ): Promise { for (const delay of [2, 4, 6, 8, 10, null]) { -- cgit v1.2.3 From 5411d65a7f8b86da46aeef23bb2c707408766135 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 22:36:12 +0200 Subject: vscode: fix, fallback to any for cmd type --- editors/code/src/ctx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index aae2c5f90..2d703af58 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -86,7 +86,7 @@ export class Ctx { } } -export type Cmd = (...args: unknown[]) => unknown; +export type Cmd = (...args: any[]) => unknown; export async function sendRequestWithRetry( client: lc.LanguageClient, -- cgit v1.2.3 From 2fd7af2a62ce0c8acb5daa6b2c179b638318f31a Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 2 Feb 2020 23:23:01 +0200 Subject: vscode: use void where possible --- editors/code/src/commands/syntax_tree.ts | 2 +- editors/code/src/ctx.ts | 8 ++++++-- editors/code/src/status_display.ts | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts index 562df50cd..211f2251f 100644 --- a/editors/code/src/commands/syntax_tree.ts +++ b/editors/code/src/commands/syntax_tree.ts @@ -55,7 +55,7 @@ export function syntaxTree(ctx: Ctx): Cmd { // We need to order this after LS updates, but there's no API for that. // Hence, good old setTimeout. -function afterLs(f: () => unknown) { +function afterLs(f: () => void) { setTimeout(f, 10); } diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 2d703af58..05d21ae56 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; + import { Config } from './config'; import { createClient } from './client'; @@ -73,11 +74,11 @@ export class Ctx { } } - get subscriptions(): { dispose(): unknown }[] { + get subscriptions(): Disposable[] { return this.extCtx.subscriptions; } - pushCleanup(d: { dispose(): unknown }) { + pushCleanup(d: Disposable) { this.extCtx.subscriptions.push(d); } @@ -86,6 +87,9 @@ export class Ctx { } } +export interface Disposable { + dispose(): void; +} export type Cmd = (...args: any[]) => unknown; export async function sendRequestWithRetry( diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts index 7345bc3f5..4317410c7 100644 --- a/editors/code/src/status_display.ts +++ b/editors/code/src/status_display.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; -import { WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressReport, WorkDoneProgressEnd } from 'vscode-languageclient'; +import { WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressReport, WorkDoneProgressEnd, Disposable } from 'vscode-languageclient'; import { Ctx } from './ctx'; @@ -14,7 +14,7 @@ export function activateStatusDisplay(ctx: Ctx) { }); } -class StatusDisplay implements vscode.Disposable { +class StatusDisplay implements vscode.Disposable, Disposable { packageName?: string; private i: number = 0; -- cgit v1.2.3 From ad57726f9181d7b80d217d7bf1b6cdca282d0982 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 3 Feb 2020 16:37:12 +0100 Subject: Use simple prng instead of a dependency closes #2999 --- editors/code/src/highlighting.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index 3d190c3ad..66216e0fc 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -1,6 +1,5 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; -import seedrandom from 'seedrandom'; import { ColorTheme, TextMateRuleSettings } from './color_theme'; @@ -70,9 +69,9 @@ interface Decoration { // Based on this HSL-based color generator: https://gist.github.com/bendc/76c48ce53299e6078a76 function fancify(seed: string, shade: 'light' | 'dark') { - const random = seedrandom(seed); + const random = randomU32Numbers(hashString(seed)) const randomInt = (min: number, max: number) => { - return Math.floor(random() * (max - min + 1)) + min; + return Math.abs(random()) % (max - min + 1) + min; }; const h = randomInt(0, 360); @@ -246,3 +245,23 @@ const TAG_TO_SCOPES = new Map([ ["keyword.unsafe", ["keyword.other.unsafe"]], ["keyword.control", ["keyword.control"]], ]); + +function randomU32Numbers(seed: number) { + let random = seed | 0; + return () => { + random ^= random << 13; + random ^= random >> 17; + random ^= random << 5; + random |= 0; + return random + } +} + +function hashString(str: string): number { + let res = 0; + for (let i = 0; i < str.length; ++i) { + const c = str.codePointAt(i)!!; + res = (res * 31 + c) & ~0; + } + return res; +} -- cgit v1.2.3 From 23ef22dd4880606c4c3dc908d30c2cbeabc37f58 Mon Sep 17 00:00:00 2001 From: Gregoire Geis Date: Sun, 2 Feb 2020 02:21:04 +0100 Subject: Add regular onEnter command, allowing onEnter to be called without overriding the type command. --- editors/code/src/commands/on_enter.ts | 51 ++++++++++++++++++++++------------- editors/code/src/main.ts | 3 ++- 2 files changed, 35 insertions(+), 19 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts index 6f61883cd..1b3d3d741 100644 --- a/editors/code/src/commands/on_enter.ts +++ b/editors/code/src/commands/on_enter.ts @@ -1,28 +1,43 @@ +import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import { applySourceChange, SourceChange } from '../source_change'; import { Cmd, Ctx } from '../ctx'; -export function onEnter(ctx: Ctx): Cmd { +async function handleKeypress(ctx: Ctx) { + const editor = ctx.activeRustEditor; + const client = ctx.client; + if (!editor) return false; + if (!client) return false; + + const request: lc.TextDocumentPositionParams = { + textDocument: { uri: editor.document.uri.toString() }, + position: client.code2ProtocolConverter.asPosition( + editor.selection.active, + ), + }; + const change = await client.sendRequest( + 'rust-analyzer/onEnter', + request, + ); + if (!change) return false; + + await applySourceChange(ctx, change); + return true; +} + +export function onEnterOverride(ctx: Ctx): Cmd { return async (event: { text: string }) => { - const editor = ctx.activeRustEditor; - const client = ctx.client; - if (!editor || event.text !== '\n') return false; - if (!client) return false; + if (event.text === '\n') { + handleKeypress(ctx); + } + }; +} - const request: lc.TextDocumentPositionParams = { - textDocument: { uri: editor.document.uri.toString() }, - position: client.code2ProtocolConverter.asPosition( - editor.selection.active, - ), - }; - const change = await client.sendRequest( - 'rust-analyzer/onEnter', - request, - ); - if (!change) return false; +export function onEnter(ctx: Ctx): Cmd { + return async () => { + if (handleKeypress(ctx)) return; - await applySourceChange(ctx, change); - return true; + await vscode.commands.executeCommand('default:type', { text: '\n' }); }; } diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 6813c3c4c..5c061e72f 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -21,6 +21,7 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('expandMacro', commands.expandMacro); ctx.registerCommand('run', commands.run); ctx.registerCommand('reload', commands.reload); + ctx.registerCommand('onEnter', commands.onEnter); // Internal commands which are invoked by the server. ctx.registerCommand('runSingle', commands.runSingle); @@ -29,7 +30,7 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); if (ctx.config.enableEnhancedTyping) { - ctx.overrideCommand('type', commands.onEnter); + ctx.overrideCommand('type', commands.onEnterOverride); } activateStatusDisplay(ctx); -- cgit v1.2.3 From b70ad7e5f3d524204fab88fe2a8c5a6fbef9e88e Mon Sep 17 00:00:00 2001 From: Gregoire Geis Date: Mon, 3 Feb 2020 20:24:50 +0100 Subject: Remove enableEnhancedTyping and type overriding infrastructure. --- editors/code/src/commands/on_enter.ts | 10 +--------- editors/code/src/ctx.ts | 24 ------------------------ editors/code/src/main.ts | 3 --- 3 files changed, 1 insertion(+), 36 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts index 1b3d3d741..ac582b423 100644 --- a/editors/code/src/commands/on_enter.ts +++ b/editors/code/src/commands/on_enter.ts @@ -26,17 +26,9 @@ async function handleKeypress(ctx: Ctx) { return true; } -export function onEnterOverride(ctx: Ctx): Cmd { - return async (event: { text: string }) => { - if (event.text === '\n') { - handleKeypress(ctx); - } - }; -} - export function onEnter(ctx: Ctx): Cmd { return async () => { - if (handleKeypress(ctx)) return; + if (await handleKeypress(ctx)) return; await vscode.commands.executeCommand('default:type', { text: '\n' }); }; diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 05d21ae56..aa75943bf 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -50,30 +50,6 @@ export class Ctx { this.pushCleanup(d); } - overrideCommand(name: string, factory: (ctx: Ctx) => Cmd) { - const defaultCmd = `default:${name}`; - const override = factory(this); - const original = (...args: unknown[]) => - vscode.commands.executeCommand(defaultCmd, ...args); - try { - const d = vscode.commands.registerCommand( - name, - async (...args: unknown[]) => { - if (!(await override(...args))) { - return await original(...args); - } - }, - ); - this.pushCleanup(d); - } catch (_) { - vscode.window.showWarningMessage( - 'Enhanced typing feature is disabled because of incompatibility ' + - 'with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: ' + - 'https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings', - ); - } - } - get subscriptions(): Disposable[] { return this.extCtx.subscriptions; } diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 5c061e72f..efc31b2e2 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -29,9 +29,6 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('applySourceChange', commands.applySourceChange); ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); - if (ctx.config.enableEnhancedTyping) { - ctx.overrideCommand('type', commands.onEnterOverride); - } activateStatusDisplay(ctx); activateHighlighting(ctx); -- cgit v1.2.3 From 875dc6d1a4973f70cd48b797ae755d1bd7a83fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Geis?= Date: Tue, 4 Feb 2020 01:44:12 +0100 Subject: Merge two if statements into one in editors/code/src/commands/on_enter.ts. Co-Authored-By: Veetaha --- editors/code/src/commands/on_enter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts index ac582b423..c636234da 100644 --- a/editors/code/src/commands/on_enter.ts +++ b/editors/code/src/commands/on_enter.ts @@ -8,7 +8,7 @@ async function handleKeypress(ctx: Ctx) { const editor = ctx.activeRustEditor; const client = ctx.client; if (!editor) return false; - if (!client) return false; + if (!editor || !client) return false; const request: lc.TextDocumentPositionParams = { textDocument: { uri: editor.document.uri.toString() }, -- cgit v1.2.3 From b89b22e43eb7e821674e0022f4061442b9e29394 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 5 Feb 2020 00:13:46 +0200 Subject: vscode: yet another refactor commit --- editors/code/src/client.ts | 29 ++++++++++++----------------- editors/code/src/color_theme.ts | 18 +++++++++--------- editors/code/src/commands/on_enter.ts | 2 +- editors/code/src/config.ts | 4 ++-- editors/code/src/highlighting.ts | 8 ++++---- editors/code/src/main.ts | 2 +- 6 files changed, 29 insertions(+), 34 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 1778c4e9f..7e7e909dd 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -7,25 +7,21 @@ import { Config } from './config'; export function createClient(config: Config): lc.LanguageClient { // '.' Is the fallback if no folder is open - // TODO?: Workspace folders support Uri's (eg: file://test.txt). It might be a good idea to test if the uri points to a file. - let folder: string = '.'; - if (workspace.workspaceFolders !== undefined) { - folder = workspace.workspaceFolders[0].uri.fsPath.toString(); - } + // TODO?: Workspace folders support Uri's (eg: file://test.txt). + // It might be a good idea to test if the uri points to a file. + const workspaceFolderPath = workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; - const command = expandPathResolving(config.raLspServerPath); - if (spawnSync(command, ["--version"]).status !== 0) { + const raLspServerPath = expandPathResolving(config.raLspServerPath); + if (spawnSync(raLspServerPath, ["--version"]).status !== 0) { window.showErrorMessage( - `Unable to execute '${command} --version' - -Perhaps it is not in $PATH? - -PATH=${process.env.PATH} -`); + `Unable to execute '${raLspServerPath} --version'\n\n` + + `Perhaps it is not in $PATH?\n\n` + + `PATH=${process.env.PATH}\n` + ); } const run: lc.Executable = { - command, - options: { cwd: folder }, + command: raLspServerPath, + options: { cwd: workspaceFolderPath }, }; const serverOptions: lc.ServerOptions = { run, @@ -43,8 +39,7 @@ PATH=${process.env.PATH} cargoWatchEnable: config.cargoWatchOptions.enable, cargoWatchArgs: config.cargoWatchOptions.arguments, cargoWatchCommand: config.cargoWatchOptions.command, - cargoWatchAllTargets: - config.cargoWatchOptions.allTargets, + cargoWatchAllTargets: config.cargoWatchOptions.allTargets, excludeGlobs: config.excludeGlobs, useClientWatching: config.useClientWatching, featureFlags: config.featureFlags, diff --git a/editors/code/src/color_theme.ts b/editors/code/src/color_theme.ts index 7e10c7f79..a6957a76e 100644 --- a/editors/code/src/color_theme.ts +++ b/editors/code/src/color_theme.ts @@ -33,6 +33,7 @@ export class ColorTheme { : typeof rule.scope === 'string' ? [rule.scope] : rule.scope; + for (const scope of scopes) { res.rules.set(scope, rule.settings); } @@ -69,13 +70,13 @@ function loadThemeNamed(themeName: string): ColorTheme { ); } - const themePaths = vscode.extensions.all + const themePaths: string[] = vscode.extensions.all .filter(isTheme) - .flatMap(ext => { - return ext.packageJSON.contributes.themes + .flatMap( + ext => ext.packageJSON.contributes.themes .filter((it: any) => (it.id || it.label) === themeName) - .map((it: any) => path.join(ext.extensionPath, it.path)); - }); + .map((it: any) => path.join(ext.extensionPath, it.path)) + ); const res = new ColorTheme(); for (const themePath of themePaths) { @@ -96,13 +97,12 @@ function loadThemeFile(themePath: string): ColorTheme { return new ColorTheme(); } const obj = jsonc.parse(text); - const tokenColors = obj?.tokenColors ?? []; + const tokenColors: TextMateRule[] = obj?.tokenColors ?? []; const res = ColorTheme.fromRules(tokenColors); - for (const include in obj?.include ?? []) { + for (const include of obj?.include ?? []) { const includePath = path.join(path.dirname(themePath), include); - const tmp = loadThemeFile(includePath); - res.mergeFrom(tmp); + res.mergeFrom(loadThemeFile(includePath)); } return res; diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts index c636234da..25eaebcbe 100644 --- a/editors/code/src/commands/on_enter.ts +++ b/editors/code/src/commands/on_enter.ts @@ -7,7 +7,7 @@ import { Cmd, Ctx } from '../ctx'; async function handleKeypress(ctx: Ctx) { const editor = ctx.activeRustEditor; const client = ctx.client; - if (!editor) return false; + if (!editor || !client) return false; const request: lc.TextDocumentPositionParams = { diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index fc21c8813..c750b2d5c 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -23,9 +23,9 @@ export class Config { lruCapacity: null | number = null; displayInlayHints = true; maxInlayHintLength: null | number = null; - excludeGlobs = []; + excludeGlobs: string[] = []; useClientWatching = true; - featureFlags = {}; + featureFlags: Record = {}; // for internal use withSysroot: null | boolean = null; cargoWatchOptions: CargoWatchOptions = { diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index 66216e0fc..e90fb8acc 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -69,7 +69,7 @@ interface Decoration { // Based on this HSL-based color generator: https://gist.github.com/bendc/76c48ce53299e6078a76 function fancify(seed: string, shade: 'light' | 'dark') { - const random = randomU32Numbers(hashString(seed)) + const random = randomU32Numbers(hashString(seed)); const randomInt = (min: number, max: number) => { return Math.abs(random()) % (max - min + 1) + min; }; @@ -253,14 +253,14 @@ function randomU32Numbers(seed: number) { random ^= random >> 17; random ^= random << 5; random |= 0; - return random - } + return random; + }; } function hashString(str: string): number { let res = 0; for (let i = 0; i < str.length; ++i) { - const c = str.codePointAt(i)!!; + const c = str.codePointAt(i)!; res = (res * 31 + c) & ~0; } return res; diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index efc31b2e2..5efce41f4 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -6,7 +6,7 @@ import { activateStatusDisplay } from './status_display'; import { Ctx } from './ctx'; import { activateHighlighting } from './highlighting'; -let ctx!: Ctx; +let ctx: Ctx | undefined; export async function activate(context: vscode.ExtensionContext) { ctx = new Ctx(context); -- cgit v1.2.3 From 8153b60e1d8abdcefbf6c7c9657f1ce65a216d7a Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 5 Feb 2020 22:39:47 +0200 Subject: vscode: eliminate floating promises and insane amount of resource handle leaks --- editors/code/src/commands/index.ts | 2 +- editors/code/src/commands/syntax_tree.ts | 2 ++ editors/code/src/config.ts | 2 +- editors/code/src/highlighting.ts | 2 ++ editors/code/src/inlay_hints.ts | 34 ++++++++++++++++++++------------ editors/code/src/status_display.ts | 10 ++++++---- 6 files changed, 33 insertions(+), 19 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index 5a4c1df5e..aee969432 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts @@ -35,7 +35,7 @@ export function showReferences(ctx: Ctx): Cmd { export function applySourceChange(ctx: Ctx): Cmd { return async (change: sourceChange.SourceChange) => { - sourceChange.applySourceChange(ctx, change); + await sourceChange.applySourceChange(ctx, change); }; } diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts index 211f2251f..7dde66ad1 100644 --- a/editors/code/src/commands/syntax_tree.ts +++ b/editors/code/src/commands/syntax_tree.ts @@ -22,6 +22,7 @@ export function syntaxTree(ctx: Ctx): Cmd { if (doc.languageId !== 'rust') return; afterLs(() => tdcp.eventEmitter.fire(tdcp.uri)); }, + null, ctx.subscriptions, ); @@ -30,6 +31,7 @@ export function syntaxTree(ctx: Ctx): Cmd { if (!editor || editor.document.languageId !== 'rust') return; tdcp.eventEmitter.fire(tdcp.uri); }, + null, ctx.subscriptions, ); diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index fc21c8813..585229ed0 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -45,7 +45,7 @@ export class Config { private prevCargoWatchOptions: null | CargoWatchOptions = null; constructor(ctx: vscode.ExtensionContext) { - vscode.workspace.onDidChangeConfiguration(_ => this.refresh(), ctx.subscriptions); + vscode.workspace.onDidChangeConfiguration(_ => this.refresh(), null, ctx.subscriptions); this.refresh(); } diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts index 66216e0fc..22458a391 100644 --- a/editors/code/src/highlighting.ts +++ b/editors/code/src/highlighting.ts @@ -32,6 +32,7 @@ export function activateHighlighting(ctx: Ctx) { vscode.workspace.onDidChangeConfiguration( _ => highlighter.removeHighlights(), + null, ctx.subscriptions, ); @@ -52,6 +53,7 @@ export function activateHighlighting(ctx: Ctx) { ); highlighter.setHighlights(editor, decorations); }, + null, ctx.subscriptions, ); } diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index ae7510183..1c019a51b 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts @@ -5,19 +5,27 @@ import { Ctx, sendRequestWithRetry } from './ctx'; export function activateInlayHints(ctx: Ctx) { const hintsUpdater = new HintsUpdater(ctx); - vscode.window.onDidChangeVisibleTextEditors(async _ => { - await hintsUpdater.refresh(); - }, ctx.subscriptions); - - vscode.workspace.onDidChangeTextDocument(async e => { - if (e.contentChanges.length === 0) return; - if (e.document.languageId !== 'rust') return; - await hintsUpdater.refresh(); - }, ctx.subscriptions); - - vscode.workspace.onDidChangeConfiguration(_ => { - hintsUpdater.setEnabled(ctx.config.displayInlayHints); - }, ctx.subscriptions); + vscode.window.onDidChangeVisibleTextEditors( + async _ => hintsUpdater.refresh(), + null, + ctx.subscriptions + ); + + vscode.workspace.onDidChangeTextDocument( + async event => { + if (event.contentChanges.length !== 0) return; + if (event.document.languageId !== 'rust') return; + await hintsUpdater.refresh(); + }, + null, + ctx.subscriptions + ); + + vscode.workspace.onDidChangeConfiguration( + async _ => hintsUpdater.setEnabled(ctx.config.displayInlayHints), + null, + ctx.subscriptions + ); ctx.onDidRestart(_ => hintsUpdater.setEnabled(ctx.config.displayInlayHints)); } diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts index 4317410c7..51dbf388b 100644 --- a/editors/code/src/status_display.ts +++ b/editors/code/src/status_display.ts @@ -9,12 +9,14 @@ const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', ' export function activateStatusDisplay(ctx: Ctx) { const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command); ctx.pushCleanup(statusDisplay); - ctx.onDidRestart(client => { - client.onProgress(WorkDoneProgress.type, 'rustAnalyzer/cargoWatcher', params => statusDisplay.handleProgressNotification(params)); - }); + ctx.onDidRestart(client => ctx.pushCleanup(client.onProgress( + WorkDoneProgress.type, + 'rustAnalyzer/cargoWatcher', + params => statusDisplay.handleProgressNotification(params) + ))); } -class StatusDisplay implements vscode.Disposable, Disposable { +class StatusDisplay implements Disposable { packageName?: string; private i: number = 0; -- cgit v1.2.3 From 1bdb78a89f6618527f2dc23f8f76e83ee77e3ea5 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Fri, 7 Feb 2020 00:09:13 +0200 Subject: vscode: add FIXME about language client shared resource protection --- editors/code/src/ctx.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'editors/code/src') diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index aa75943bf..a4dcc3037 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -11,6 +11,9 @@ export class Ctx { // deal with it. // // Ideally, this should be replaced with async getter though. + // FIXME: this actually needs syncronization of some kind (check how + // vscode deals with `deactivate()` call when extension has some work scheduled + // on the event loop to get a better picture of what we can do here) client: lc.LanguageClient | null = null; private extCtx: vscode.ExtensionContext; private onDidRestartHooks: Array<(client: lc.LanguageClient) => void> = []; -- cgit v1.2.3 From 3e0e4e90aeeff25db674f8db562c611bd8016482 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Fri, 7 Feb 2020 03:11:24 +0200 Subject: added fetchLatestArtifactMetadata() and downloadFile() functions --- editors/code/src/github/download_file.ts | 26 ++++++++++ .../src/github/fetch_latest_artifact_metadata.ts | 55 ++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 editors/code/src/github/download_file.ts create mode 100644 editors/code/src/github/fetch_latest_artifact_metadata.ts (limited to 'editors/code/src') diff --git a/editors/code/src/github/download_file.ts b/editors/code/src/github/download_file.ts new file mode 100644 index 000000000..f40750be9 --- /dev/null +++ b/editors/code/src/github/download_file.ts @@ -0,0 +1,26 @@ +import fetch from "node-fetch"; +import { throttle } from "throttle-debounce"; +import * as fs from "fs"; + +export async function downloadFile( + url: string, + destFilePath: fs.PathLike, + onProgress: (readBytes: number, totalBytes: number) => void +): Promise { + onProgress = throttle(100, /* noTrailing: */ true, onProgress); + + const response = await fetch(url); + + const totalBytes = Number(response.headers.get('content-length')); + let readBytes = 0; + + return new Promise((resolve, reject) => response.body + .on("data", (chunk: Buffer) => { + readBytes += chunk.length; + onProgress(readBytes, totalBytes); + }) + .on("end", resolve) + .on("error", reject) + .pipe(fs.createWriteStream(destFilePath)) + ); +} diff --git a/editors/code/src/github/fetch_latest_artifact_metadata.ts b/editors/code/src/github/fetch_latest_artifact_metadata.ts new file mode 100644 index 000000000..52641ca67 --- /dev/null +++ b/editors/code/src/github/fetch_latest_artifact_metadata.ts @@ -0,0 +1,55 @@ +import fetch from "node-fetch"; + +const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; + +export interface FetchLatestArtifactMetadataOpts { + repoName: string; + repoOwner: string; + artifactFileName: string; +} + +export interface ArtifactMetadata { + releaseName: string; + releaseDate: Date; + downloadUrl: string; +} + +export async function fetchLatestArtifactMetadata( + opts: FetchLatestArtifactMetadataOpts +): Promise { + + const repoOwner = encodeURIComponent(opts.repoOwner); + const repoName = encodeURIComponent(opts.repoName); + + const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; + const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; + + // We skip runtime type checks for simplicity (here we cast from `any` to `Release`) + + const response: GithubRelease = await fetch(requestUrl, { + headers: { Accept: "application/vnd.github.v3+json" } + }) + .then(res => res.json()); + + const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName); + + return !artifact ? null : { + releaseName: response.name, + releaseDate: new Date(response.published_at), + downloadUrl: artifact.browser_download_url + }; + + // Noise denotes tremendous amount of data that we are not using here + interface GithubRelease { + name: string; + published_at: Date; + assets: Array<{ + browser_download_url: string; + + [noise: string]: unknown; + }>; + + [noise: string]: unknown; + } + +} -- cgit v1.2.3 From 5d88c1db38200896d2e4af7836fec95097adf509 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 04:22:44 +0200 Subject: vscode: amended config to use binary from globalStoragePath, added ui for downloading --- editors/code/src/client.ts | 22 +--- editors/code/src/config.ts | 56 ++++++++-- editors/code/src/ctx.ts | 6 +- editors/code/src/github/download_file.ts | 26 ----- .../src/github/fetch_latest_artifact_metadata.ts | 55 ---------- editors/code/src/installation/download_file.ts | 26 +++++ .../installation/fetch_latest_artifact_metadata.ts | 47 ++++++++ editors/code/src/installation/interfaces.ts | 26 +++++ editors/code/src/installation/language_server.ts | 119 +++++++++++++++++++++ 9 files changed, 277 insertions(+), 106 deletions(-) delete mode 100644 editors/code/src/github/download_file.ts delete mode 100644 editors/code/src/github/fetch_latest_artifact_metadata.ts create mode 100644 editors/code/src/installation/download_file.ts create mode 100644 editors/code/src/installation/fetch_latest_artifact_metadata.ts create mode 100644 editors/code/src/installation/interfaces.ts create mode 100644 editors/code/src/installation/language_server.ts (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 7e7e909dd..7639ed44b 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -1,24 +1,18 @@ -import { homedir } from 'os'; import * as lc from 'vscode-languageclient'; -import { spawnSync } from 'child_process'; import { window, workspace } from 'vscode'; import { Config } from './config'; +import { ensureLanguageServerBinary } from './installation/language_server'; -export function createClient(config: Config): lc.LanguageClient { +export async function createClient(config: Config): Promise { // '.' Is the fallback if no folder is open // TODO?: Workspace folders support Uri's (eg: file://test.txt). // It might be a good idea to test if the uri points to a file. const workspaceFolderPath = workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; - const raLspServerPath = expandPathResolving(config.raLspServerPath); - if (spawnSync(raLspServerPath, ["--version"]).status !== 0) { - window.showErrorMessage( - `Unable to execute '${raLspServerPath} --version'\n\n` + - `Perhaps it is not in $PATH?\n\n` + - `PATH=${process.env.PATH}\n` - ); - } + const raLspServerPath = await ensureLanguageServerBinary(config.raLspServerSource); + if (!raLspServerPath) return null; + const run: lc.Executable = { command: raLspServerPath, options: { cwd: workspaceFolderPath }, @@ -87,9 +81,3 @@ export function createClient(config: Config): lc.LanguageClient { res.registerProposedFeatures(); return res; } -function expandPathResolving(path: string) { - if (path.startsWith('~/')) { - return path.replace('~', homedir()); - } - return path; -} diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 524620433..aca5dab5a 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -1,4 +1,6 @@ +import * as os from "os"; import * as vscode from 'vscode'; +import { BinarySource, BinarySourceType } from "./installation/interfaces"; const RA_LSP_DEBUG = process.env.__RA_LSP_SERVER_DEBUG; @@ -16,10 +18,24 @@ export interface CargoFeatures { } export class Config { + readonly raLspServerGithubArtifactName = { + linux: "ra_lsp_server-linux", + darwin: "ra_lsp_server-mac", + win32: "ra_lsp_server-windows.exe", + aix: null, + android: null, + freebsd: null, + openbsd: null, + sunos: null, + cygwin: null, + netbsd: null, + }[process.platform]; + + raLspServerSource!: null | BinarySource; + highlightingOn = true; rainbowHighlightingOn = false; enableEnhancedTyping = true; - raLspServerPath = RA_LSP_DEBUG || 'ra_lsp_server'; lruCapacity: null | number = null; displayInlayHints = true; maxInlayHintLength: null | number = null; @@ -45,11 +61,20 @@ export class Config { private prevCargoWatchOptions: null | CargoWatchOptions = null; constructor(ctx: vscode.ExtensionContext) { - vscode.workspace.onDidChangeConfiguration(_ => this.refresh(), null, ctx.subscriptions); - this.refresh(); + vscode.workspace.onDidChangeConfiguration(_ => this.refresh(ctx), null, ctx.subscriptions); + this.refresh(ctx); + } + + private static expandPathResolving(path: string) { + if (path.startsWith('~/')) { + return path.replace('~', os.homedir()); + } + return path; } - private refresh() { + // FIXME: revisit the logic for `if (.has(...)) config.get(...)` set default + // values only in one place (i.e. remove default values from non-readonly members declarations) + private refresh(ctx: vscode.ExtensionContext) { const config = vscode.workspace.getConfiguration('rust-analyzer'); let requireReloadMessage = null; @@ -82,9 +107,26 @@ export class Config { this.prevEnhancedTyping = this.enableEnhancedTyping; } - if (config.has('raLspServerPath')) { - this.raLspServerPath = - RA_LSP_DEBUG || (config.get('raLspServerPath') as string); + { + const raLspServerPath = RA_LSP_DEBUG ?? config.get("raLspServerPath"); + if (raLspServerPath) { + this.raLspServerSource = { + type: BinarySourceType.ExplicitPath, + path: Config.expandPathResolving(raLspServerPath) + }; + } else if (this.raLspServerGithubArtifactName) { + this.raLspServerSource = { + type: BinarySourceType.GithubBinary, + dir: ctx.globalStoragePath, + file: this.raLspServerGithubArtifactName, + repo: { + name: "rust-analyzer", + owner: "rust-analyzer", + } + }; + } else { + this.raLspServerSource = null; + } } if (config.has('cargo-watch.enable')) { diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index a4dcc3037..f0e2d72f7 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -29,7 +29,11 @@ export class Ctx { await old.stop(); } this.client = null; - const client = createClient(this.config); + const client = await createClient(this.config); + if (!client) { + throw new Error("Rust Analyzer Language Server is not available"); + } + this.pushCleanup(client.start()); await client.onReady(); diff --git a/editors/code/src/github/download_file.ts b/editors/code/src/github/download_file.ts deleted file mode 100644 index f40750be9..000000000 --- a/editors/code/src/github/download_file.ts +++ /dev/null @@ -1,26 +0,0 @@ -import fetch from "node-fetch"; -import { throttle } from "throttle-debounce"; -import * as fs from "fs"; - -export async function downloadFile( - url: string, - destFilePath: fs.PathLike, - onProgress: (readBytes: number, totalBytes: number) => void -): Promise { - onProgress = throttle(100, /* noTrailing: */ true, onProgress); - - const response = await fetch(url); - - const totalBytes = Number(response.headers.get('content-length')); - let readBytes = 0; - - return new Promise((resolve, reject) => response.body - .on("data", (chunk: Buffer) => { - readBytes += chunk.length; - onProgress(readBytes, totalBytes); - }) - .on("end", resolve) - .on("error", reject) - .pipe(fs.createWriteStream(destFilePath)) - ); -} diff --git a/editors/code/src/github/fetch_latest_artifact_metadata.ts b/editors/code/src/github/fetch_latest_artifact_metadata.ts deleted file mode 100644 index 52641ca67..000000000 --- a/editors/code/src/github/fetch_latest_artifact_metadata.ts +++ /dev/null @@ -1,55 +0,0 @@ -import fetch from "node-fetch"; - -const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; - -export interface FetchLatestArtifactMetadataOpts { - repoName: string; - repoOwner: string; - artifactFileName: string; -} - -export interface ArtifactMetadata { - releaseName: string; - releaseDate: Date; - downloadUrl: string; -} - -export async function fetchLatestArtifactMetadata( - opts: FetchLatestArtifactMetadataOpts -): Promise { - - const repoOwner = encodeURIComponent(opts.repoOwner); - const repoName = encodeURIComponent(opts.repoName); - - const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; - const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; - - // We skip runtime type checks for simplicity (here we cast from `any` to `Release`) - - const response: GithubRelease = await fetch(requestUrl, { - headers: { Accept: "application/vnd.github.v3+json" } - }) - .then(res => res.json()); - - const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName); - - return !artifact ? null : { - releaseName: response.name, - releaseDate: new Date(response.published_at), - downloadUrl: artifact.browser_download_url - }; - - // Noise denotes tremendous amount of data that we are not using here - interface GithubRelease { - name: string; - published_at: Date; - assets: Array<{ - browser_download_url: string; - - [noise: string]: unknown; - }>; - - [noise: string]: unknown; - } - -} diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts new file mode 100644 index 000000000..7b537e114 --- /dev/null +++ b/editors/code/src/installation/download_file.ts @@ -0,0 +1,26 @@ +import fetch from "node-fetch"; +import { throttle } from "throttle-debounce"; +import * as fs from "fs"; + +export async function downloadFile( + url: string, + destFilePath: fs.PathLike, + onProgress: (readBytes: number, totalBytes: number) => void +): Promise { + onProgress = throttle(1000, /* noTrailing: */ true, onProgress); + + const response = await fetch(url); + + const totalBytes = Number(response.headers.get('content-length')); + let readBytes = 0; + + return new Promise((resolve, reject) => response.body + .on("data", (chunk: Buffer) => { + readBytes += chunk.length; + onProgress(readBytes, totalBytes); + }) + .on("end", resolve) + .on("error", reject) + .pipe(fs.createWriteStream(destFilePath)) + ); +} diff --git a/editors/code/src/installation/fetch_latest_artifact_metadata.ts b/editors/code/src/installation/fetch_latest_artifact_metadata.ts new file mode 100644 index 000000000..f07431aac --- /dev/null +++ b/editors/code/src/installation/fetch_latest_artifact_metadata.ts @@ -0,0 +1,47 @@ +import fetch from "node-fetch"; +import { GithubRepo, ArtifactMetadata } from "./interfaces"; + +const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; + +export interface FetchLatestArtifactMetadataOpts { + repo: GithubRepo; + artifactFileName: string; +} + +export async function fetchLatestArtifactMetadata( + opts: FetchLatestArtifactMetadataOpts +): Promise { + + const repoOwner = encodeURIComponent(opts.repo.owner); + const repoName = encodeURIComponent(opts.repo.name); + + const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; + const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; + + // We skip runtime type checks for simplicity (here we cast from `any` to `Release`) + + const response: GithubRelease = await fetch(requestUrl, { + headers: { Accept: "application/vnd.github.v3+json" } + }) + .then(res => res.json()); + + const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName); + + return !artifact ? null : { + releaseName: response.name, + downloadUrl: artifact.browser_download_url + }; + + // Noise denotes tremendous amount of data that we are not using here + interface GithubRelease { + name: string; + assets: Array<{ + browser_download_url: string; + + [noise: string]: unknown; + }>; + + [noise: string]: unknown; + } + +} diff --git a/editors/code/src/installation/interfaces.ts b/editors/code/src/installation/interfaces.ts new file mode 100644 index 000000000..f54e24e26 --- /dev/null +++ b/editors/code/src/installation/interfaces.ts @@ -0,0 +1,26 @@ +export interface GithubRepo { + name: string; + owner: string; +} + +export interface ArtifactMetadata { + releaseName: string; + downloadUrl: string; +} + + +export enum BinarySourceType { ExplicitPath, GithubBinary } + +export type BinarySource = EplicitPathSource | GithubBinarySource; + +export interface EplicitPathSource { + type: BinarySourceType.ExplicitPath; + path: string; +} + +export interface GithubBinarySource { + type: BinarySourceType.GithubBinary; + repo: GithubRepo; + dir: string; + file: string; +} diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts new file mode 100644 index 000000000..2b3ce6621 --- /dev/null +++ b/editors/code/src/installation/language_server.ts @@ -0,0 +1,119 @@ +import { unwrapNotNil } from "ts-not-nil"; +import { spawnSync } from "child_process"; +import * as vscode from "vscode"; +import * as path from "path"; +import { strict as assert } from "assert"; +import { promises as fs } from "fs"; + +import { BinarySource, BinarySourceType, GithubBinarySource } from "./interfaces"; +import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata"; +import { downloadFile } from "./download_file"; + +export async function downloadLatestLanguageServer( + {file: artifactFileName, dir: installationDir, repo}: GithubBinarySource +) { + const binaryMetadata = await fetchLatestArtifactMetadata({ artifactFileName, repo }); + + const { + releaseName, + downloadUrl + } = unwrapNotNil(binaryMetadata, `Latest GitHub release lacks "${artifactFileName}" file`); + + await fs.mkdir(installationDir).catch(err => assert.strictEqual( + err && err.code, + "EEXIST", + `Couldn't create directory "${installationDir}" to download `+ + `language server binary: ${err.message}` + )); + + const installationPath = path.join(installationDir, artifactFileName); + + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + cancellable: false, // FIXME: add support for canceling download? + title: `Downloading language server ${releaseName}` + }, + async (progress, _) => { + let lastPrecentage = 0; + await downloadFile(downloadUrl, installationPath, (readBytes, totalBytes) => { + const newPercentage = (readBytes / totalBytes) * 100; + progress.report({ + message: newPercentage.toFixed(0) + "%", + increment: newPercentage - lastPrecentage + }); + + lastPrecentage = newPercentage; + }); + } + ); + + await fs.chmod(installationPath, 111); // Set xxx permissions +} +export async function ensureLanguageServerBinary( + langServerSource: null | BinarySource +): Promise { + + if (!langServerSource) { + vscode.window.showErrorMessage( + "Unfortunately we don't ship binaries for your platform yet. " + + "You need to manually clone rust-analyzer repository and " + + "run `cargo xtask install --server` to build the language server from sources. " + + "If you feel that your platform should be supported, please create an issue " + + "about that [here](https://github.com/rust-analyzer/rust-analyzer/issues) and we " + + "will consider it." + ); + return null; + } + + switch (langServerSource.type) { + case BinarySourceType.ExplicitPath: { + if (isBinaryAvailable(langServerSource.path)) { + return langServerSource.path; + } + vscode.window.showErrorMessage( + `Unable to execute ${'`'}${langServerSource.path} --version${'`'}. ` + + "To use the bundled language server, set `rust-analyzer.raLspServerPath` " + + "value to `null` or remove it from the settings to use it by default." + ); + return null; + } + case BinarySourceType.GithubBinary: { + const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file); + + if (!isBinaryAvailable(bundledBinaryPath)) { + const userResponse = await vscode.window.showInformationMessage( + `Language server binary for rust-analyzer was not found. ` + + `Do you want to download it now?`, + "Download now", "Cancel" + ); + if (userResponse !== "Download now") return null; + + try { + await downloadLatestLanguageServer(langServerSource); + } catch (err) { + await vscode.window.showErrorMessage( + `Failed to download language server from ${langServerSource.repo.name} ` + + `GitHub repository: ${err.message}` + ); + return null; + } + + + assert( + isBinaryAvailable(bundledBinaryPath), + "Downloaded language server binary is not functional" + ); + + vscode.window.showInformationMessage( + "Rust analyzer language server was successfully installed" + ); + } + return bundledBinaryPath; + } + } + + function isBinaryAvailable(binaryPath: string) { + return spawnSync(binaryPath, ["--version"]).status === 0; + } +} -- cgit v1.2.3 From f7ef72db64e75dadf6f7cae9d739a0a6e8d8f4b4 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 20:07:00 +0200 Subject: vscode: changed chmod value to 755 as per @lnicola --- editors/code/src/installation/language_server.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index 2b3ce6621..8d8c62952 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -12,7 +12,7 @@ import { downloadFile } from "./download_file"; export async function downloadLatestLanguageServer( {file: artifactFileName, dir: installationDir, repo}: GithubBinarySource ) { - const binaryMetadata = await fetchLatestArtifactMetadata({ artifactFileName, repo }); + const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName); const { releaseName, @@ -20,7 +20,7 @@ export async function downloadLatestLanguageServer( } = unwrapNotNil(binaryMetadata, `Latest GitHub release lacks "${artifactFileName}" file`); await fs.mkdir(installationDir).catch(err => assert.strictEqual( - err && err.code, + err?.code, "EEXIST", `Couldn't create directory "${installationDir}" to download `+ `language server binary: ${err.message}` @@ -48,7 +48,7 @@ export async function downloadLatestLanguageServer( } ); - await fs.chmod(installationPath, 111); // Set xxx permissions + await fs.chmod(installationPath, 755); // Set (rwx, r_x, r_x) permissions } export async function ensureLanguageServerBinary( langServerSource: null | BinarySource -- cgit v1.2.3 From 6ef912f9259a78495fdba6a37bef7d78c4e0a4fd Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 20:18:33 +0200 Subject: vscode: converted fetchLatestArtifactMetadata params to positional, added docs --- .../installation/fetch_latest_artifact_metadata.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/fetch_latest_artifact_metadata.ts b/editors/code/src/installation/fetch_latest_artifact_metadata.ts index f07431aac..cda955af2 100644 --- a/editors/code/src/installation/fetch_latest_artifact_metadata.ts +++ b/editors/code/src/installation/fetch_latest_artifact_metadata.ts @@ -3,29 +3,28 @@ import { GithubRepo, ArtifactMetadata } from "./interfaces"; const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; -export interface FetchLatestArtifactMetadataOpts { - repo: GithubRepo; - artifactFileName: string; -} - +/** + * Fetches the latest release from GitHub `repo` and returns metadata about + * `artifactFileName` shipped with this release or `null` if no such artifact was published. + */ export async function fetchLatestArtifactMetadata( - opts: FetchLatestArtifactMetadataOpts + repo: GithubRepo, artifactFileName: string ): Promise { - const repoOwner = encodeURIComponent(opts.repo.owner); - const repoName = encodeURIComponent(opts.repo.name); + const repoOwner = encodeURIComponent(repo.owner); + const repoName = encodeURIComponent(repo.name); const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/latest`; const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; - // We skip runtime type checks for simplicity (here we cast from `any` to `Release`) + // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) const response: GithubRelease = await fetch(requestUrl, { headers: { Accept: "application/vnd.github.v3+json" } }) .then(res => res.json()); - const artifact = response.assets.find(artifact => artifact.name === opts.artifactFileName); + const artifact = response.assets.find(artifact => artifact.name === artifactFileName); return !artifact ? null : { releaseName: response.name, @@ -36,6 +35,7 @@ export async function fetchLatestArtifactMetadata( interface GithubRelease { name: string; assets: Array<{ + name: string; browser_download_url: string; [noise: string]: unknown; -- cgit v1.2.3 From 4e85254444cfaf34fefc253ecd0b43b786e31dd8 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 21:03:27 +0200 Subject: vscode: add docs to installation module interfaces and sanity check to donloadFile() --- editors/code/src/installation/download_file.ts | 10 +++++++- editors/code/src/installation/interfaces.ts | 33 +++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts index 7b537e114..0cc5fc0cb 100644 --- a/editors/code/src/installation/download_file.ts +++ b/editors/code/src/installation/download_file.ts @@ -1,17 +1,25 @@ import fetch from "node-fetch"; import { throttle } from "throttle-debounce"; import * as fs from "fs"; +import { strict as assert } from "assert"; +/** + * Downloads file from `url` and stores it at `destFilePath`. + * `onProgress` callback is periodically called to track the progress of downloading, + * it gets the already read and total amount of bytes to read as its parameters. + */ export async function downloadFile( url: string, destFilePath: fs.PathLike, onProgress: (readBytes: number, totalBytes: number) => void ): Promise { - onProgress = throttle(1000, /* noTrailing: */ true, onProgress); + onProgress = throttle(500, /* noTrailing: */ true, onProgress); const response = await fetch(url); const totalBytes = Number(response.headers.get('content-length')); + assert(!Number.isNaN(totalBytes), "Sanity check of content-length protocol"); + let readBytes = 0; return new Promise((resolve, reject) => response.body diff --git a/editors/code/src/installation/interfaces.ts b/editors/code/src/installation/interfaces.ts index f54e24e26..03eac5b79 100644 --- a/editors/code/src/installation/interfaces.ts +++ b/editors/code/src/installation/interfaces.ts @@ -3,24 +3,51 @@ export interface GithubRepo { owner: string; } +/** + * Metadata about particular artifact retrieved from GitHub releases. + */ export interface ArtifactMetadata { releaseName: string; downloadUrl: string; } - +/** + * Type tag for `BinarySource` discriminated union. + */ export enum BinarySourceType { ExplicitPath, GithubBinary } -export type BinarySource = EplicitPathSource | GithubBinarySource; +/** + * Represents the source of a binary artifact which is either specified by the user + * explicitly, or bundled by this extension from GitHub releases. + */ +export type BinarySource = ExplicitPathSource | GithubBinarySource; + -export interface EplicitPathSource { +export interface ExplicitPathSource { type: BinarySourceType.ExplicitPath; + + /** + * Filesystem path to the binary specified by the user explicitly. + */ path: string; } export interface GithubBinarySource { type: BinarySourceType.GithubBinary; + + /** + * Repository where the binary is stored. + */ repo: GithubRepo; + + /** + * Directory on the filesystem where the bundled binary is stored. + */ dir: string; + + /** + * Name of the binary file. It is stored under the same name on GitHub releases + * and in local `.dir`. + */ file: string; } -- cgit v1.2.3 From 9791b6a8de7149d97cdf9880d86bfc9e640c8297 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 21:24:29 +0200 Subject: vscode: add name to the second unused argument of withProgress() callback --- editors/code/src/installation/language_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index 8d8c62952..b75d3a00a 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -34,7 +34,7 @@ export async function downloadLatestLanguageServer( cancellable: false, // FIXME: add support for canceling download? title: `Downloading language server ${releaseName}` }, - async (progress, _) => { + async (progress, _cancellationToken) => { let lastPrecentage = 0; await downloadFile(downloadUrl, installationPath, (readBytes, totalBytes) => { const newPercentage = (readBytes / totalBytes) * 100; -- cgit v1.2.3 From bdd88c2fad272f96a8212e5230010f7c02b4d15d Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sat, 8 Feb 2020 21:25:03 +0200 Subject: vscode: reduce throttle latency of downloadFile() progress callback for smoother UX --- editors/code/src/installation/download_file.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts index 0cc5fc0cb..ec16dcd66 100644 --- a/editors/code/src/installation/download_file.ts +++ b/editors/code/src/installation/download_file.ts @@ -13,7 +13,7 @@ export async function downloadFile( destFilePath: fs.PathLike, onProgress: (readBytes: number, totalBytes: number) => void ): Promise { - onProgress = throttle(500, /* noTrailing: */ true, onProgress); + onProgress = throttle(200, /* noTrailing: */ true, onProgress); const response = await fetch(url); -- cgit v1.2.3 From 539daf4454e3f11424a469e8fba26cacb325176a Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 00:27:04 +0200 Subject: vscode: refactor platform artifact name query to switch statement, move BinarySource union variants into a namespace --- editors/code/src/client.ts | 2 +- editors/code/src/config.ts | 89 ++++++++++++++---------- editors/code/src/installation/interfaces.ts | 58 +++++++-------- editors/code/src/installation/language_server.ts | 10 +-- 4 files changed, 89 insertions(+), 70 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index 7639ed44b..2e3d4aba2 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -10,7 +10,7 @@ export async function createClient(config: Config): Promise("raLspServerPath"); + + if (raLspServerPath) { + return { + type: BinarySource.Type.ExplicitPath, + path: Config.expandPathResolving(raLspServerPath) + }; + } + + const prebuiltBinaryName = Config.prebuiltLangServerFileName(process.platform); + + return !prebuiltBinaryName ? null : { + type: BinarySource.Type.GithubRelease, + dir: ctx.globalStoragePath, + file: prebuiltBinaryName, + repo: { + name: "rust-analyzer", + owner: "rust-analyzer", + } + }; + } + + // FIXME: revisit the logic for `if (.has(...)) config.get(...)` set default // values only in one place (i.e. remove default values from non-readonly members declarations) private refresh(ctx: vscode.ExtensionContext) { @@ -107,27 +144,7 @@ export class Config { this.prevEnhancedTyping = this.enableEnhancedTyping; } - { - const raLspServerPath = RA_LSP_DEBUG ?? config.get("raLspServerPath"); - if (raLspServerPath) { - this.raLspServerSource = { - type: BinarySourceType.ExplicitPath, - path: Config.expandPathResolving(raLspServerPath) - }; - } else if (this.raLspServerGithubArtifactName) { - this.raLspServerSource = { - type: BinarySourceType.GithubBinary, - dir: ctx.globalStoragePath, - file: this.raLspServerGithubArtifactName, - repo: { - name: "rust-analyzer", - owner: "rust-analyzer", - } - }; - } else { - this.raLspServerSource = null; - } - } + this.langServerSource = Config.langServerBinarySource(ctx, config); if (config.has('cargo-watch.enable')) { this.cargoWatchOptions.enable = config.get( diff --git a/editors/code/src/installation/interfaces.ts b/editors/code/src/installation/interfaces.ts index 03eac5b79..8039d0b90 100644 --- a/editors/code/src/installation/interfaces.ts +++ b/editors/code/src/installation/interfaces.ts @@ -11,43 +11,45 @@ export interface ArtifactMetadata { downloadUrl: string; } -/** - * Type tag for `BinarySource` discriminated union. - */ -export enum BinarySourceType { ExplicitPath, GithubBinary } - /** * Represents the source of a binary artifact which is either specified by the user * explicitly, or bundled by this extension from GitHub releases. */ -export type BinarySource = ExplicitPathSource | GithubBinarySource; - - -export interface ExplicitPathSource { - type: BinarySourceType.ExplicitPath; +export type BinarySource = BinarySource.ExplicitPath | BinarySource.GithubRelease; +export namespace BinarySource { /** - * Filesystem path to the binary specified by the user explicitly. + * Type tag for `BinarySource` discriminated union. */ - path: string; -} + export const enum Type { ExplicitPath, GithubRelease } -export interface GithubBinarySource { - type: BinarySourceType.GithubBinary; + export interface ExplicitPath { + type: Type.ExplicitPath; - /** - * Repository where the binary is stored. - */ - repo: GithubRepo; + /** + * Filesystem path to the binary specified by the user explicitly. + */ + path: string; + } - /** - * Directory on the filesystem where the bundled binary is stored. - */ - dir: string; + export interface GithubRelease { + type: Type.GithubRelease; + + /** + * Repository where the binary is stored. + */ + repo: GithubRepo; + + /** + * Directory on the filesystem where the bundled binary is stored. + */ + dir: string; + + /** + * Name of the binary file. It is stored under the same name on GitHub releases + * and in local `.dir`. + */ + file: string; + } - /** - * Name of the binary file. It is stored under the same name on GitHub releases - * and in local `.dir`. - */ - file: string; } diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index b75d3a00a..522d59eb5 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -5,12 +5,12 @@ import * as path from "path"; import { strict as assert } from "assert"; import { promises as fs } from "fs"; -import { BinarySource, BinarySourceType, GithubBinarySource } from "./interfaces"; +import { BinarySource } from "./interfaces"; import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata"; import { downloadFile } from "./download_file"; export async function downloadLatestLanguageServer( - {file: artifactFileName, dir: installationDir, repo}: GithubBinarySource + {file: artifactFileName, dir: installationDir, repo}: BinarySource.GithubRelease ) { const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName); @@ -67,7 +67,7 @@ export async function ensureLanguageServerBinary( } switch (langServerSource.type) { - case BinarySourceType.ExplicitPath: { + case BinarySource.Type.ExplicitPath: { if (isBinaryAvailable(langServerSource.path)) { return langServerSource.path; } @@ -78,7 +78,7 @@ export async function ensureLanguageServerBinary( ); return null; } - case BinarySourceType.GithubBinary: { + case BinarySource.Type.GithubRelease: { const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file); if (!isBinaryAvailable(bundledBinaryPath)) { @@ -106,7 +106,7 @@ export async function ensureLanguageServerBinary( ); vscode.window.showInformationMessage( - "Rust analyzer language server was successfully installed" + "Rust analyzer language server was successfully installed 🦀" ); } return bundledBinaryPath; -- cgit v1.2.3 From 8f291c0089700ab17fafddde33dc12515ba45662 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 00:28:32 +0200 Subject: vscode: refactor comment --- editors/code/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index f216ab461..5aed8c9f3 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -78,7 +78,7 @@ export class Config { case "sunos": case "cygwin": case "netbsd": return null; - // The list of platforms is exhaustive see (`NodeJS.Platform` type definition) + // The list of platforms is exhaustive (see `NodeJS.Platform` type definition) } } -- cgit v1.2.3 From fd6a98ef6e8cb3ee4d578bf90ad327df548dd1c5 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 00:42:51 +0200 Subject: vscode: rename raLspServer variable to langServer --- editors/code/src/config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 5aed8c9f3..46394600b 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -86,12 +86,12 @@ export class Config { ctx: vscode.ExtensionContext, config: vscode.WorkspaceConfiguration ): null | BinarySource { - const raLspServerPath = RA_LSP_DEBUG ?? config.get("raLspServerPath"); + const langServerPath = RA_LSP_DEBUG ?? config.get("raLspServerPath"); - if (raLspServerPath) { + if (langServerPath) { return { type: BinarySource.Type.ExplicitPath, - path: Config.expandPathResolving(raLspServerPath) + path: Config.expandPathResolving(langServerPath) }; } -- cgit v1.2.3 From d08ae7e82f9eb4abb92f1274ea361acb21fd7b87 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 00:58:53 +0200 Subject: vscode: minor names and message contents changes --- editors/code/src/ctx.ts | 5 ++++- editors/code/src/installation/language_server.ts | 16 ++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index f0e2d72f7..70042a479 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -31,7 +31,10 @@ export class Ctx { this.client = null; const client = await createClient(this.config); if (!client) { - throw new Error("Rust Analyzer Language Server is not available"); + throw new Error( + "Rust Analyzer Language Server is not available. " + + "Please, ensure its [proper installation](https://github.com/rust-analyzer/rust-analyzer/tree/master/docs/user#vs-code)." + ); } this.pushCleanup(client.start()); diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index 522d59eb5..d09fc63a7 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -72,19 +72,19 @@ export async function ensureLanguageServerBinary( return langServerSource.path; } vscode.window.showErrorMessage( - `Unable to execute ${'`'}${langServerSource.path} --version${'`'}. ` + - "To use the bundled language server, set `rust-analyzer.raLspServerPath` " + + `Unable to run ${langServerSource.path} binary. ` + + "To use the pre-built language server, set `rust-analyzer.raLspServerPath` " + "value to `null` or remove it from the settings to use it by default." ); return null; } case BinarySource.Type.GithubRelease: { - const bundledBinaryPath = path.join(langServerSource.dir, langServerSource.file); + const prebuiltBinaryPath = path.join(langServerSource.dir, langServerSource.file); - if (!isBinaryAvailable(bundledBinaryPath)) { + if (!isBinaryAvailable(prebuiltBinaryPath)) { const userResponse = await vscode.window.showInformationMessage( - `Language server binary for rust-analyzer was not found. ` + - `Do you want to download it now?`, + "Language server binary for rust-analyzer was not found. " + + "Do you want to download it now?", "Download now", "Cancel" ); if (userResponse !== "Download now") return null; @@ -101,7 +101,7 @@ export async function ensureLanguageServerBinary( assert( - isBinaryAvailable(bundledBinaryPath), + isBinaryAvailable(prebuiltBinaryPath), "Downloaded language server binary is not functional" ); @@ -109,7 +109,7 @@ export async function ensureLanguageServerBinary( "Rust analyzer language server was successfully installed 🦀" ); } - return bundledBinaryPath; + return prebuiltBinaryPath; } } -- cgit v1.2.3 From a3e3fba7bf9cbaa51d39ecfd2b111472fdbf4cb3 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 12:54:51 +0200 Subject: vscode: fix chmod to octal literal Co-Authored-By: Aleksey Kladov --- editors/code/src/installation/language_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index d09fc63a7..ea1228e46 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -48,7 +48,7 @@ export async function downloadLatestLanguageServer( } ); - await fs.chmod(installationPath, 755); // Set (rwx, r_x, r_x) permissions + await fs.chmod(installationPath, 0o755); // Set (rwx, r_x, r_x) permissions } export async function ensureLanguageServerBinary( langServerSource: null | BinarySource -- cgit v1.2.3 From 3159e87c49cd43677927ba7baa8f12c1232183a1 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 13:36:36 +0200 Subject: vscode: refactor levels of code nesting and string literals quotes --- editors/code/src/installation/language_server.ts | 56 +++++++++++++----------- 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index ea1228e46..e571cbc98 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -71,9 +71,10 @@ export async function ensureLanguageServerBinary( if (isBinaryAvailable(langServerSource.path)) { return langServerSource.path; } + vscode.window.showErrorMessage( `Unable to run ${langServerSource.path} binary. ` + - "To use the pre-built language server, set `rust-analyzer.raLspServerPath` " + + `To use the pre-built language server, set "rust-analyzer.raLspServerPath" ` + "value to `null` or remove it from the settings to use it by default." ); return null; @@ -81,34 +82,37 @@ export async function ensureLanguageServerBinary( case BinarySource.Type.GithubRelease: { const prebuiltBinaryPath = path.join(langServerSource.dir, langServerSource.file); - if (!isBinaryAvailable(prebuiltBinaryPath)) { - const userResponse = await vscode.window.showInformationMessage( - "Language server binary for rust-analyzer was not found. " + - "Do you want to download it now?", - "Download now", "Cancel" - ); - if (userResponse !== "Download now") return null; - - try { - await downloadLatestLanguageServer(langServerSource); - } catch (err) { - await vscode.window.showErrorMessage( - `Failed to download language server from ${langServerSource.repo.name} ` + - `GitHub repository: ${err.message}` - ); - return null; - } - - - assert( - isBinaryAvailable(prebuiltBinaryPath), - "Downloaded language server binary is not functional" - ); + if (isBinaryAvailable(prebuiltBinaryPath)) { + return prebuiltBinaryPath; + } - vscode.window.showInformationMessage( - "Rust analyzer language server was successfully installed 🦀" + const userResponse = await vscode.window.showInformationMessage( + "Language server binary for rust-analyzer was not found. " + + "Do you want to download it now?", + "Download now", "Cancel" + ); + if (userResponse !== "Download now") return null; + + try { + await downloadLatestLanguageServer(langServerSource); + } catch (err) { + await vscode.window.showErrorMessage( + `Failed to download language server from ${langServerSource.repo.name} ` + + `GitHub repository: ${err.message}` ); + return null; } + + + assert( + isBinaryAvailable(prebuiltBinaryPath), + "Downloaded language server binary is not functional" + ); + + vscode.window.showInformationMessage( + "Rust analyzer language server was successfully installed 🦀" + ); + return prebuiltBinaryPath; } } -- cgit v1.2.3 From 34241b9af966208d73f37f1cdf7f862f2590d846 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 13:39:54 +0200 Subject: vscode: remove noise data fields declarations as per @matklad --- editors/code/src/installation/fetch_latest_artifact_metadata.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/fetch_latest_artifact_metadata.ts b/editors/code/src/installation/fetch_latest_artifact_metadata.ts index cda955af2..f1019e089 100644 --- a/editors/code/src/installation/fetch_latest_artifact_metadata.ts +++ b/editors/code/src/installation/fetch_latest_artifact_metadata.ts @@ -31,17 +31,12 @@ export async function fetchLatestArtifactMetadata( downloadUrl: artifact.browser_download_url }; - // Noise denotes tremendous amount of data that we are not using here + // We omit declaration of tremendous amount of fields that we are not using here interface GithubRelease { name: string; assets: Array<{ name: string; browser_download_url: string; - - [noise: string]: unknown; }>; - - [noise: string]: unknown; } - } -- cgit v1.2.3 From 7a09274e52dc00f7d4e3a040686aa1eb1e075671 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 13:45:06 +0200 Subject: vscode: refactor inverted ternaries to if statements as per @matklad --- editors/code/src/config.ts | 4 +++- editors/code/src/installation/fetch_latest_artifact_metadata.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 46394600b..d5f3da2ed 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -97,7 +97,9 @@ export class Config { const prebuiltBinaryName = Config.prebuiltLangServerFileName(process.platform); - return !prebuiltBinaryName ? null : { + if (!prebuiltBinaryName) return null; + + return { type: BinarySource.Type.GithubRelease, dir: ctx.globalStoragePath, file: prebuiltBinaryName, diff --git a/editors/code/src/installation/fetch_latest_artifact_metadata.ts b/editors/code/src/installation/fetch_latest_artifact_metadata.ts index f1019e089..9141c92ef 100644 --- a/editors/code/src/installation/fetch_latest_artifact_metadata.ts +++ b/editors/code/src/installation/fetch_latest_artifact_metadata.ts @@ -26,7 +26,9 @@ export async function fetchLatestArtifactMetadata( const artifact = response.assets.find(artifact => artifact.name === artifactFileName); - return !artifact ? null : { + if (!artifact) return null; + + return { releaseName: response.name, downloadUrl: artifact.browser_download_url }; -- cgit v1.2.3 From a63659badb75d22ad834b7524e77505790c10dd0 Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 13:59:27 +0200 Subject: vscode: replaced unwrapNotNil() with ! as per @matklad --- editors/code/src/installation/language_server.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index e571cbc98..a169eae47 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -1,4 +1,3 @@ -import { unwrapNotNil } from "ts-not-nil"; import { spawnSync } from "child_process"; import * as vscode from "vscode"; import * as path from "path"; @@ -12,12 +11,9 @@ import { downloadFile } from "./download_file"; export async function downloadLatestLanguageServer( {file: artifactFileName, dir: installationDir, repo}: BinarySource.GithubRelease ) { - const binaryMetadata = await fetchLatestArtifactMetadata(repo, artifactFileName); - - const { - releaseName, - downloadUrl - } = unwrapNotNil(binaryMetadata, `Latest GitHub release lacks "${artifactFileName}" file`); + const { releaseName, downloadUrl } = (await fetchLatestArtifactMetadata( + repo, artifactFileName + ))!; await fs.mkdir(installationDir).catch(err => assert.strictEqual( err?.code, -- cgit v1.2.3 From f3240e22c6de69b408a83b59e85f40fb913acfab Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 14:18:05 +0200 Subject: vscode: move throtting of download progress to call site --- editors/code/src/installation/download_file.ts | 8 +++---- editors/code/src/installation/language_server.ts | 27 ++++++++++++++---------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts index ec16dcd66..53bf46d78 100644 --- a/editors/code/src/installation/download_file.ts +++ b/editors/code/src/installation/download_file.ts @@ -1,20 +1,18 @@ import fetch from "node-fetch"; -import { throttle } from "throttle-debounce"; import * as fs from "fs"; import { strict as assert } from "assert"; /** * Downloads file from `url` and stores it at `destFilePath`. - * `onProgress` callback is periodically called to track the progress of downloading, - * it gets the already read and total amount of bytes to read as its parameters. + * `onProgress` callback is called on recieveing each chunk of bytes + * to track the progress of downloading, it gets the already read and total + * amount of bytes to read as its parameters. */ export async function downloadFile( url: string, destFilePath: fs.PathLike, onProgress: (readBytes: number, totalBytes: number) => void ): Promise { - onProgress = throttle(200, /* noTrailing: */ true, onProgress); - const response = await fetch(url); const totalBytes = Number(response.headers.get('content-length')); diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index a169eae47..c1f37f978 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -1,8 +1,9 @@ -import { spawnSync } from "child_process"; import * as vscode from "vscode"; import * as path from "path"; import { strict as assert } from "assert"; import { promises as fs } from "fs"; +import { spawnSync } from "child_process"; +import { throttle } from "throttle-debounce"; import { BinarySource } from "./interfaces"; import { fetchLatestArtifactMetadata } from "./fetch_latest_artifact_metadata"; @@ -28,19 +29,23 @@ export async function downloadLatestLanguageServer( { location: vscode.ProgressLocation.Notification, cancellable: false, // FIXME: add support for canceling download? - title: `Downloading language server ${releaseName}` + title: `Downloading language server (${releaseName})` }, async (progress, _cancellationToken) => { let lastPrecentage = 0; - await downloadFile(downloadUrl, installationPath, (readBytes, totalBytes) => { - const newPercentage = (readBytes / totalBytes) * 100; - progress.report({ - message: newPercentage.toFixed(0) + "%", - increment: newPercentage - lastPrecentage - }); - - lastPrecentage = newPercentage; - }); + await downloadFile(downloadUrl, installationPath, throttle( + 200, + /* noTrailing: */ true, + (readBytes, totalBytes) => { + const newPercentage = (readBytes / totalBytes) * 100; + progress.report({ + message: newPercentage.toFixed(0) + "%", + increment: newPercentage - lastPrecentage + }); + + lastPrecentage = newPercentage; + }) + ); } ); -- cgit v1.2.3 From 7cba77ed4e4207b2e24b8dd57723368c2717bb2a Mon Sep 17 00:00:00 2001 From: Veetaha Date: Sun, 9 Feb 2020 15:01:00 +0200 Subject: vscode: added logging when donloading binaries --- editors/code/src/installation/download_file.ts | 2 ++ .../installation/fetch_latest_artifact_metadata.ts | 2 ++ editors/code/src/installation/language_server.ts | 27 ++++++++++++++++++---- 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts index 53bf46d78..b51602ef9 100644 --- a/editors/code/src/installation/download_file.ts +++ b/editors/code/src/installation/download_file.ts @@ -20,6 +20,8 @@ export async function downloadFile( let readBytes = 0; + console.log("Downloading file of", totalBytes, "bytes size from", url, "to", destFilePath); + return new Promise((resolve, reject) => response.body .on("data", (chunk: Buffer) => { readBytes += chunk.length; diff --git a/editors/code/src/installation/fetch_latest_artifact_metadata.ts b/editors/code/src/installation/fetch_latest_artifact_metadata.ts index 9141c92ef..7e3700603 100644 --- a/editors/code/src/installation/fetch_latest_artifact_metadata.ts +++ b/editors/code/src/installation/fetch_latest_artifact_metadata.ts @@ -19,6 +19,8 @@ export async function fetchLatestArtifactMetadata( // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) + console.log("Issuing request for released artifacts metadata to", requestUrl); + const response: GithubRelease = await fetch(requestUrl, { headers: { Accept: "application/vnd.github.v3+json" } }) diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index c1f37f978..1ce67b8b2 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode"; import * as path from "path"; import { strict as assert } from "assert"; import { promises as fs } from "fs"; +import { promises as dns } from "dns"; import { spawnSync } from "child_process"; import { throttle } from "throttle-debounce"; @@ -25,6 +26,7 @@ export async function downloadLatestLanguageServer( const installationPath = path.join(installationDir, artifactFileName); + console.time("Downloading ra_lsp_server"); await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, @@ -48,6 +50,7 @@ export async function downloadLatestLanguageServer( ); } ); + console.timeEnd("Downloading ra_lsp_server"); await fs.chmod(installationPath, 0o755); // Set (rwx, r_x, r_x) permissions } @@ -101,15 +104,21 @@ export async function ensureLanguageServerBinary( `Failed to download language server from ${langServerSource.repo.name} ` + `GitHub repository: ${err.message}` ); + + await dns.resolve('www.google.com').catch(err => { + console.error("DNS resolution failed, there might be an issue with Internet availability"); + console.error(err); + }); + return null; } - - assert( - isBinaryAvailable(prebuiltBinaryPath), - "Downloaded language server binary is not functional" + if (!isBinaryAvailable(prebuiltBinaryPath)) assert(false, + `Downloaded language server binary is not functional.` + + `Downloaded from: ${JSON.stringify(langServerSource)}` ); + vscode.window.showInformationMessage( "Rust analyzer language server was successfully installed 🦀" ); @@ -119,6 +128,14 @@ export async function ensureLanguageServerBinary( } function isBinaryAvailable(binaryPath: string) { - return spawnSync(binaryPath, ["--version"]).status === 0; + const res = spawnSync(binaryPath, ["--version"]); + + // ACHTUNG! `res` type declaration is inherently wrong, see + // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/42221 + + console.log("Checked binary availablity via --version", res); + console.log(binaryPath, "--version output:", res.output?.map(String)); + + return res.status === 0; } } -- cgit v1.2.3