diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/code/src/ctx.ts | 13 | ||||
-rw-r--r-- | editors/code/src/inlay_hints.ts | 23 |
2 files changed, 26 insertions, 10 deletions
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index 75b3542f4..d3ef27e43 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts | |||
@@ -62,20 +62,23 @@ export class Ctx { | |||
62 | this.extCtx.subscriptions.push(d); | 62 | this.extCtx.subscriptions.push(d); |
63 | } | 63 | } |
64 | 64 | ||
65 | async sendRequestWithRetry<R>(method: string, param: any): Promise<R> { | 65 | async sendRequestWithRetry<R>(method: string, param: any, token: vscode.CancellationToken): Promise<R> { |
66 | await this.client.onReady(); | 66 | await this.client.onReady(); |
67 | const nRetries = 3; | 67 | for (const delay of [2, 4, 6, 8, 10, null]) { |
68 | for (let triesLeft = nRetries; ; triesLeft--) { | ||
69 | try { | 68 | try { |
70 | return await this.client.sendRequest(method, param); | 69 | return await this.client.sendRequest(method, param, token); |
71 | } catch (e) { | 70 | } catch (e) { |
72 | if (e.code === lc.ErrorCodes.ContentModified && triesLeft > 0) { | 71 | if (e.code === lc.ErrorCodes.ContentModified && delay !== null) { |
72 | await sleep(10 * (1 << delay)) | ||
73 | continue; | 73 | continue; |
74 | } | 74 | } |
75 | throw e; | 75 | throw e; |
76 | } | 76 | } |
77 | } | 77 | } |
78 | throw 'unreachable' | ||
78 | } | 79 | } |
79 | } | 80 | } |
80 | 81 | ||
81 | export type Cmd = (...args: any[]) => any; | 82 | export type Cmd = (...args: any[]) => any; |
83 | |||
84 | const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) | ||
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts index 16faea22e..d41297407 100644 --- a/editors/code/src/inlay_hints.ts +++ b/editors/code/src/inlay_hints.ts | |||
@@ -41,6 +41,7 @@ const typeHintDecorationType = vscode.window.createTextEditorDecorationType({ | |||
41 | }); | 41 | }); |
42 | 42 | ||
43 | class HintsUpdater { | 43 | class HintsUpdater { |
44 | private pending: Map<string, vscode.CancellationTokenSource> = new Map(); | ||
44 | private ctx: Ctx; | 45 | private ctx: Ctx; |
45 | private enabled = true; | 46 | private enabled = true; |
46 | 47 | ||
@@ -67,7 +68,8 @@ class HintsUpdater { | |||
67 | 68 | ||
68 | private async refreshEditor(editor: vscode.TextEditor): Promise<void> { | 69 | private async refreshEditor(editor: vscode.TextEditor): Promise<void> { |
69 | const newHints = await this.queryHints(editor.document.uri.toString()); | 70 | const newHints = await this.queryHints(editor.document.uri.toString()); |
70 | const newDecorations = (newHints ? newHints : []).map(hint => ({ | 71 | if (newHints == null) return; |
72 | const newDecorations = newHints.map(hint => ({ | ||
71 | range: hint.range, | 73 | range: hint.range, |
72 | renderOptions: { | 74 | renderOptions: { |
73 | after: { | 75 | after: { |
@@ -98,9 +100,20 @@ class HintsUpdater { | |||
98 | const request: InlayHintsParams = { | 100 | const request: InlayHintsParams = { |
99 | textDocument: { uri: documentUri }, | 101 | textDocument: { uri: documentUri }, |
100 | }; | 102 | }; |
101 | return this.ctx.sendRequestWithRetry<InlayHint[] | null>( | 103 | let tokenSource = new vscode.CancellationTokenSource(); |
102 | 'rust-analyzer/inlayHints', | 104 | let prev = this.pending.get(documentUri); |
103 | request, | 105 | if (prev) prev.cancel() |
104 | ); | 106 | this.pending.set(documentUri, tokenSource); |
107 | try { | ||
108 | return await this.ctx.sendRequestWithRetry<InlayHint[] | null>( | ||
109 | 'rust-analyzer/inlayHints', | ||
110 | request, | ||
111 | tokenSource.token, | ||
112 | ); | ||
113 | } finally { | ||
114 | if (!tokenSource.token.isCancellationRequested) { | ||
115 | this.pending.delete(documentUri) | ||
116 | } | ||
117 | } | ||
105 | } | 118 | } |
106 | } | 119 | } |