]> git.lizzy.rs Git - rust.git/blob - editors/code/src/ctx.ts
Rearrange code
[rust.git] / editors / code / src / ctx.ts
1 import * as vscode from 'vscode';
2 import * as lc from 'vscode-languageclient';
3 import { Server } from './server';
4 import { Config } from './config';
5
6 export class Ctx {
7     private extCtx: vscode.ExtensionContext;
8
9     constructor(extCtx: vscode.ExtensionContext) {
10         this.extCtx = extCtx;
11     }
12
13     get client(): lc.LanguageClient {
14         return Server.client;
15     }
16
17     get config(): Config {
18         return Server.config;
19     }
20
21     get activeRustEditor(): vscode.TextEditor | undefined {
22         const editor = vscode.window.activeTextEditor;
23         return editor && editor.document.languageId === 'rust'
24             ? editor
25             : undefined;
26     }
27
28     registerCommand(name: string, factory: (ctx: Ctx) => Cmd) {
29         const fullName = `rust-analyzer.${name}`;
30         const cmd = factory(this);
31         const d = vscode.commands.registerCommand(fullName, cmd);
32         this.pushCleanup(d);
33     }
34
35     overrideCommand(name: string, factory: (ctx: Ctx) => Cmd) {
36         const defaultCmd = `default:${name}`;
37         const override = factory(this);
38         const original = (...args: any[]) =>
39             vscode.commands.executeCommand(defaultCmd, ...args);
40         try {
41             const d = vscode.commands.registerCommand(
42                 name,
43                 async (...args: any[]) => {
44                     if (!(await override(...args))) {
45                         return await original(...args);
46                     }
47                 },
48             );
49             this.pushCleanup(d);
50         } catch (_) {
51             vscode.window.showWarningMessage(
52                 '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',
53             );
54         }
55     }
56
57     get subscriptions(): { dispose(): any }[] {
58         return this.extCtx.subscriptions;
59     }
60
61     pushCleanup(d: { dispose(): any }) {
62         this.extCtx.subscriptions.push(d);
63     }
64
65     async sendRequestWithRetry<R>(
66         method: string,
67         param: any,
68         token?: vscode.CancellationToken,
69     ): Promise<R> {
70         await this.client.onReady();
71         for (const delay of [2, 4, 6, 8, 10, null]) {
72             try {
73                 return await this.client.sendRequest(method, param, token);
74             } catch (e) {
75                 if (
76                     e.code === lc.ErrorCodes.ContentModified &&
77                     delay !== null
78                 ) {
79                     await sleep(10 * (1 << delay));
80                     continue;
81                 }
82                 throw e;
83             }
84         }
85         throw 'unreachable';
86     }
87 }
88
89 export type Cmd = (...args: any[]) => any;
90
91 const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));